home *** CD-ROM | disk | FTP | other *** search
/ Creating Your Own America Online Web Pages / Creating Your Own America Online Web Pages.iso / TOOLS / TEX2RTF / SOURCES.ZIP / SRC / RTFUTILS.CC < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-27  |  115.0 KB  |  4,682 lines

  1. /*
  2.  * rtfutils.cc
  3.  *
  4.  * Utility functions for helping convert Latex files
  5.  * into RTF files suitable for compiling into WinHelp
  6.  * files.
  7.  *
  8.  * Julian Smart September 1993
  9.  *
  10.  */
  11.  
  12. #include "wx.h"
  13. #include "tex2any.h"
  14. #include "tex2rtf.h"
  15. #include <ctype.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include "bmputils.h"
  19.  
  20. wxList itemizeStack;
  21. static int indentLevel = 0;
  22. static int forbidParindent = 0; // if > 0, no parindent (e.g. in center environment)
  23. int forbidResetPar = 0; // If > 0, don't reset memory of having output a new par
  24.  
  25. static char *contentsLineSection = NULL;
  26. static char *contentsLineValue = NULL;
  27. static TexChunk *descriptionItemArg = NULL;
  28. static wxStringList environmentStack; // Stack of paragraph styles we need to remember
  29. static int footnoteCount = 0;
  30. static int citeCount = 1;
  31. extern char *FileRoot;
  32. extern Bool winHelp;
  33. extern Bool startedSections;
  34. extern FILE *Contents;
  35. extern FILE *Chapters;
  36. extern FILE *Popups;
  37. extern char *RTFCharset;
  38. // This is defined in the Tex2Any library and isn't in use after parsing
  39. extern char *BigBuffer;
  40. // Are we in verbatim mode? If so, format differently.
  41. static Bool inVerbatim = FALSE;
  42.  
  43. // Linear RTF requires us to set the style per section.
  44. static char *currentNumberStyle = NULL;
  45. static int currentItemSep = 8;
  46. static int CurrentTextWidth = 8640; // Say, six inches
  47. static int CurrentLeftMarginOdd = 400;
  48. static int CurrentLeftMarginEven = 1440;
  49. static int CurrentRightMarginOdd = 1440;
  50. static int CurrentRightMarginEven = 400;
  51. static int CurrentMarginParWidth = 2000;
  52. static int CurrentMarginParSep = 400;  // Gap between marginpar and text
  53. static int CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
  54. static int GutterWidth = 2300;
  55.  
  56. // Two-column table dimensions, in twips
  57. static int TwoColWidthA = 1500;
  58. static int TwoColWidthB = 3000;
  59. static int TwoColSpacing = 1;
  60.  
  61. const int PageWidth = 12242; // 8.25 inches wide for A4
  62.  
  63. /*
  64.  * Table dimensions
  65.  *
  66.  */
  67.  
  68. struct ColumnData
  69. {
  70.   char justification; // l, r, c
  71.   int width;          // -1 or a width in twips
  72.   int spacing;        // Space between columns in twips
  73.   Bool leftBorder;
  74.   Bool rightBorder;
  75. };
  76.  
  77. ColumnData TableData[20];
  78. Bool inTabular = FALSE;
  79. Bool startRows = FALSE;
  80. Bool tableVerticalLineLeft = FALSE;
  81. Bool tableVerticalLineRight = FALSE;
  82. int noColumns = 0;   // Current number of columns in table
  83. static int ruleTop = 0;
  84. static int ruleBottom = 0;
  85. int currentRowNumber = 0;
  86.  
  87. /*
  88.  * Flag to say we've just issued a \par\pard command, so don't
  89.  * repeat this unnecessarily.
  90.  *
  91.  */
  92.  
  93. Bool issuedNewParagraph = FALSE;
  94. // Need to know whether we're in a table or figure for benefit
  95. // of listoffigures/listoftables
  96. Bool inFigure = FALSE;
  97. Bool inTable = FALSE;
  98.  
  99. /*
  100.  * Current topics
  101.  *
  102.  */
  103. static char *CurrentChapterName = NULL;
  104. static char *CurrentSectionName = NULL;
  105. static char *CurrentSubsectionName = NULL;
  106. static char *CurrentTopic = NULL;
  107.  
  108. void SetCurrentTopic(char *s)
  109. {
  110.   if (CurrentTopic) delete[] CurrentTopic;
  111.   CurrentTopic = copystring(s);
  112. }
  113.  
  114. void SetCurrentChapterName(char *s)
  115. {
  116.   if (CurrentChapterName) delete[] CurrentChapterName;
  117.   CurrentChapterName = copystring(s);
  118.   SetCurrentTopic(s);
  119. }
  120. void SetCurrentSectionName(char *s)
  121. {
  122.   if (CurrentSectionName) delete[] CurrentSectionName;
  123.   CurrentSectionName = copystring(s);
  124.   SetCurrentTopic(s);
  125. }
  126. void SetCurrentSubsectionName(char *s)
  127. {
  128.   if (CurrentSubsectionName) delete[] CurrentSubsectionName;
  129.   CurrentSubsectionName = copystring(s);
  130.   SetCurrentTopic(s);
  131. }
  132.  
  133. // Hash table for lists of keywords for topics (WinHelp).
  134. static wxHashTable TopicTable(wxKEY_STRING);
  135. void AddKeyWordForTopic(char *topic, char *entry)
  136. {
  137.   wxStringList *list = (wxStringList *)TopicTable.Get(topic);
  138.   if (!list)
  139.   {
  140.     list = new wxStringList;
  141.     TopicTable.Put(topic, (wxObject *)list);
  142.   }
  143.     
  144.   if (!list->Member(entry))
  145.     list->Add(entry);
  146. }
  147.  
  148. void SplitIndexEntry(char *entry, char *buf1, char *buf2)
  149. {
  150.   int len = strlen(entry); int i = 0;
  151.   while ((i < len) && entry[i] != '!')
  152.   { buf1[i] = entry[i]; i ++; }
  153.   buf1[i] = 0; buf2[0] = 0; int j = 0;
  154.  
  155.   if (entry[i] == '!')
  156.   {
  157.     i ++;
  158.     while (i < len) { buf2[j] = entry[i]; i ++; j++; }
  159.     buf2[j] = 0;
  160.   }
  161. }
  162.  
  163. /*
  164.  * Output topic index entries in WinHelp RTF
  165.  *
  166.  */
  167. void GenerateKeywordsForTopic(char *topic)
  168. {
  169.   wxStringList *list = (wxStringList *)TopicTable.Get(topic);
  170.   if (list)
  171.   {
  172.     wxNode *node = list->First();
  173.     while (node)
  174.     {
  175.       char *s = (char *)node->Data();
  176.  
  177.       // Must separate out main entry form subentry (only 1 subentry allowed)
  178.       char buf1[100]; char buf2[100];
  179.       SplitIndexEntry(s, buf1, buf2);
  180.  
  181.       TexOutput("K{\\footnote ");
  182.       TexOutput(buf1);
  183.       if (strlen(buf2) > 0)
  184.       {
  185.         // Output subentry
  186.         TexOutput(", ");
  187.         TexOutput(buf2);
  188.       }
  189.       TexOutput("}\n");
  190.       node = node->Next();
  191.     }
  192.   }
  193. }
  194.  
  195. /*
  196.  * Output index entry in linear RTF
  197.  *
  198.  */
  199.  
  200. void GenerateIndexEntry(char *entry)
  201. {
  202.   char buf1[100]; char buf2[100];
  203.   SplitIndexEntry(entry, buf1, buf2);
  204.  
  205.   TexOutput("{\\xe\\v {");
  206.   TexOutput(buf1);
  207.   if (strlen(buf2) > 0)
  208.   {
  209.     TexOutput("\\:");
  210.     TexOutput(buf2);
  211.   }
  212.   TexOutput("}}");
  213. }
  214.  
  215. void ClearKeyWordTable(void)
  216. {
  217.   TopicTable.BeginFind();
  218.   wxNode *node = TopicTable.Next();
  219.   while (node)
  220.   {
  221.     wxStringList *list = (wxStringList *)node->Data();
  222.     delete list;
  223.     node = TopicTable.Next();
  224.   }
  225.   TopicTable.Clear();
  226. }
  227.  
  228.  /*
  229.   * Write a suitable RTF header.
  230.   *
  231.   */
  232.   
  233. void WriteColourTable(FILE *fd)
  234. {
  235.   fprintf(fd, "{\\colortbl");
  236.   wxNode *node = ColourTable.First();
  237.   while (node)
  238.   {
  239.     ColourTableEntry *entry = (ColourTableEntry *)node->Data();
  240.     fprintf(fd, "\\red%d\\green%d\\blue%d;\n", entry->red, entry->green, entry->blue);
  241.     node = node->Next();
  242.   }
  243.   fprintf(fd, "}");
  244. }
  245.  
  246. /*
  247.  * Write heading style
  248.  *
  249.  */
  250.  
  251. void WriteHeadingStyle(FILE *fd, int heading)
  252. {
  253.   switch (heading)
  254.   {
  255.     case 1:
  256.     {
  257.       fprintf(fd, "\\b\\fs%d", chapterFont*2);
  258.       break;
  259.     }
  260.     case 2:
  261.     {
  262.       fprintf(fd, "\\b\\fs%d", sectionFont*2);
  263.       break;
  264.     }
  265.     case 3:
  266.     {
  267.       fprintf(fd, "\\b\\fs%d", subsectionFont*2);
  268.       break;
  269.     }
  270.     case 4:
  271.     {
  272.       fprintf(fd, "\\b\\fs%d", subsectionFont*2);
  273.       break;
  274.     }
  275.     default:
  276.       break;
  277.   }
  278. }
  279.  
  280. void WriteRTFHeader(FILE *fd)
  281. {
  282.   fprintf(fd, "{\\rtf1\\%s \\deff0\n", RTFCharset);
  283.   fprintf(fd, "{\\fonttbl{\\f0\\froman Times New Roman;}{\\f1\\ftech Symbol;}{\\f2\\fswiss Arial;}\n");
  284.   fprintf(fd, "{\\f3\\fmodern Courier;}{\\f4\\ftech Wingdings;}{\\f5\\ftech Monotype Sorts;}\n}");
  285.   /*
  286.    * Style sheet
  287.    */
  288.   fprintf(fd, "{\\stylesheet{\\f2\\fs20 \\snext0 Normal;}\n");
  289.   // Headings
  290.   fprintf(fd, "{\\s1 "); WriteHeadingStyle(fd, 1); fprintf(fd, "\\sbasedon0\\snext0 heading 1;}\n");
  291.   fprintf(fd, "{\\s2 "); WriteHeadingStyle(fd, 2); fprintf(fd, "\\sbasedon0\\snext0 heading 2;}\n");
  292.   fprintf(fd, "{\\s3 "); WriteHeadingStyle(fd, 3); fprintf(fd, "\\sbasedon0\\snext0 heading 3;}\n");
  293.   fprintf(fd, "{\\s4 "); WriteHeadingStyle(fd, 4); fprintf(fd, "\\sbasedon0\\snext0 heading 4;}\n");
  294.   // Table of contents styles
  295.   fprintf(fd, "{\\s20\\sb300\\tqr\\tldot\\tx8640 \\b\\f2 \\sbasedon0\\snext0 toc 1;}\n");
  296.   fprintf(fd, "{\\s21\\sb90\\tqr\\tldot\\li400\\tqr\\tx8640 \\f2\\fs20\\sbasedon0\\snext0 toc 2;}\n");
  297.   fprintf(fd, "{\\s22\\sb90\\tqr\\tldot\\li800\\tx8640 \\f2\\fs20 \\sbasedon0\\snext0 toc 3;}\n");
  298.   fprintf(fd, "{\\s23\\sb90\\tqr\\tldot\\li1200\\tx8640 \\f2\\fs20 \\sbasedon0\\snext0 toc 4;}\n");
  299.   // Index styles
  300.   fprintf(fd, "{\\s30\\fi-200\\li200\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 1;}\n");
  301.   fprintf(fd, "{\\s31\\fi-200\\li400\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 2;}\n");
  302.   fprintf(fd, "{\\s32\\fi-200\\li600\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 3;}\n");
  303.   fprintf(fd, "{\\s33\\fi-200\\li800\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 4;}\n");
  304.   fprintf(fd, "{\\s35\\qc\\sb240\\sa120 \\b\\f2\\fs26 \\sbasedon0\\snext30 index heading;}\n");
  305.   fprintf(fd, "}\n");
  306.  
  307.   WriteColourTable(fd);
  308.   fprintf(fd, "\n\\ftnbj\\ftnrestart"); // Latex default is footnotes at bottom of page, not section.
  309.   fprintf(fd, "\n");
  310. }
  311.  
  312. void OutputNumberStyle(char *numberStyle)
  313. {
  314.   if (numberStyle)
  315.   {
  316.     if (strcmp(numberStyle, "arabic") == 0)
  317.     {
  318.       TexOutput("\\pgndec");
  319.     }
  320.     else if (strcmp(numberStyle, "roman") == 0)
  321.     {
  322.       TexOutput("\\pgnlcrm");
  323.     }
  324.     else if (strcmp(numberStyle, "Roman") == 0)
  325.     {
  326.       TexOutput("\\pgnucrm");
  327.     }
  328.     else if (strcmp(numberStyle, "alph") == 0)
  329.     {
  330.       TexOutput("\\pgnlcltr");
  331.     }
  332.     else if (strcmp(numberStyle, "Alph") == 0)
  333.     {
  334.       TexOutput("\\pgnucltr");
  335.     }
  336.   }
  337. }
  338.  
  339. /*
  340.  * Write a Windows help project file
  341.  */
  342.  
  343. Bool WriteHPJ(char *filename)
  344. {
  345.   char hpjFilename[256];
  346.   char helpFile[50];
  347.   char rtfFile[50];
  348.   strcpy(hpjFilename, filename);
  349.   StripExtension(hpjFilename);
  350.   strcat(hpjFilename, ".hpj");
  351.  
  352.   strcpy(helpFile, FileNameFromPath(filename));
  353.   StripExtension(helpFile);
  354.   strcpy(rtfFile, helpFile);
  355.   strcat(helpFile, ".hlp");
  356.   strcat(rtfFile, ".rtf");
  357.   
  358.   FILE *fd = fopen(hpjFilename, "w");
  359.   if (!fd)
  360.     return FALSE;
  361.  
  362.   char *helpTitle = winHelpTitle;
  363.   if (!helpTitle)
  364.     helpTitle = "Untitled";
  365.     
  366.   fprintf(fd, "[OPTIONS]\nCOMPRESS=HIGH\nTITLE=%s\n\n", helpTitle);
  367.   fprintf(fd, "[FILES]\n%s\n\n", rtfFile);
  368.   fprintf(fd, "[CONFIG]\n");
  369.   if (useUpButton)
  370.     fprintf(fd, "CreateButton(\"Up\", \"&Up\", \"JumpId(`%s', `Contents')\")\n", helpFile);
  371.   fprintf(fd, "BrowseButtons()\n\n");
  372.   fprintf(fd, "[MAP]\n\n[BITMAPS]\n\n");
  373.   fclose(fd);
  374.   return TRUE;
  375. }
  376.  
  377.  
  378. /*
  379.  * Given a TexChunk with a string value, scans through the string
  380.  * converting Latex-isms into RTF-isms, such as 2 newlines -> \par,
  381.  * and inserting spaces at the start of lines since in Latex, a newline
  382.  * implies a space, but not in RTF.
  383.  *
  384.  */
  385.  
  386. void ProcessText2RTF(TexChunk *chunk)
  387. {
  388.   Bool changed = FALSE;
  389.   int ptr = 0;
  390.   int i = 0;
  391.   char ch = 1;
  392.   int len = strlen(chunk->value);
  393.   while (ch != 0)
  394.   {
  395.     ch = chunk->value[i];
  396.  
  397.     if (ch == 10)
  398.     {
  399.       if (inVerbatim)
  400.       {
  401.         BigBuffer[ptr] = 0; strcat(BigBuffer, "\\par\n"); ptr += 5;
  402.         i ++;
  403.         changed = TRUE;
  404.       }
  405.       else
  406.       {
  407.         // If the first character of the next line is ASCII,
  408.         // put a space in. Implicit in Latex, not in RTF.
  409.         /*
  410.           The reason this is difficult is that you don't really know
  411.           where a space would be appropriate. If you always put in a space
  412.           when you find a newline, unwanted spaces appear in the text.
  413.          */
  414.         if ((i > 0) && (len > i+1 && isascii(chunk->value[i+1]) &&
  415.                   !isspace(chunk->value[i+1])) ||
  416.             ((len > i+1 && chunk->value[i+1] == 13) &&
  417.              (len > i+2 && isascii(chunk->value[i+2]) &&
  418.               !isspace(chunk->value[i+2]))))
  419. //        if (TRUE)
  420.         {
  421.           // DOS files have a 13 after the 10
  422.           BigBuffer[ptr] = 10;
  423.           ptr ++;
  424.           i ++;
  425.           if (chunk->value[i] == 13)
  426.           {
  427.             BigBuffer[ptr] = 13;
  428.             ptr ++;
  429.             i ++;
  430.           }
  431.  
  432.           BigBuffer[ptr] = ' ';
  433.           ptr ++;
  434.  
  435.           // Note that the actual ASCII character seen is dealt with in the next
  436.           // iteration
  437.           changed = TRUE;
  438.         }
  439.         else
  440.         {
  441.           BigBuffer[ptr] = ch;
  442.           i ++;
  443.         }
  444.       }
  445.     }
  446.     else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`'))
  447.     {
  448.       BigBuffer[ptr] = '"'; ptr ++;
  449.       i += 2;
  450.       changed = TRUE;
  451.     }
  452.     else if (!inVerbatim && ch == '`') // Change ` to '
  453.     {
  454.       BigBuffer[ptr] = 39; ptr ++;
  455.       i += 1;
  456.       changed = TRUE;
  457.     }
  458.     else if (inVerbatim && ch == '\\') // Change backslash to two backslashes
  459.     {
  460.       BigBuffer[ptr] = '\\'; ptr ++;
  461.       BigBuffer[ptr] = '\\'; ptr ++;
  462.       i += 1;
  463.       changed = TRUE;
  464.     }
  465.     else if (inVerbatim && (ch == '{' || ch == '}')) // Escape the curly bracket
  466.     {
  467.       BigBuffer[ptr] = '\\'; ptr ++;
  468.       BigBuffer[ptr] = ch; ptr ++;
  469.       i += 1;
  470.       changed = TRUE;
  471.     }
  472.     else
  473.     {
  474.       BigBuffer[ptr] = ch;
  475.       i ++;
  476.       ptr ++;
  477.     }
  478.   }
  479.   BigBuffer[ptr] = 0;
  480.  
  481.   if (changed)
  482.   {
  483.     delete[] chunk->value;
  484.     chunk->value = copystring(BigBuffer);
  485.   }
  486. }
  487.  
  488. /*
  489.  * Scan through all chunks starting from the given one,
  490.  * calling ProcessText2RTF to convert Latex-isms to RTF-isms.
  491.  * This should be called after Tex2Any has parsed the file,
  492.  * and before TraverseDocument is called.
  493.  *
  494.  */
  495.  
  496. void Text2RTF(TexChunk *chunk)
  497. {
  498.   Tex2RTFYield();
  499.   if (stopRunning) return;
  500.  
  501.   switch (chunk->type)
  502.   {
  503.     case CHUNK_TYPE_MACRO:
  504.     {
  505.       TexMacroDef *def = chunk->def;
  506.       if (def && def->ignore)
  507.         return;
  508.  
  509.       if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB))
  510.         inVerbatim = TRUE;
  511.  
  512.       wxNode *node = chunk->children.First();
  513.       while (node)
  514.       {
  515.         TexChunk *child_chunk = (TexChunk *)node->Data();
  516.         Text2RTF(child_chunk);
  517.         node = node->Next();
  518.       }
  519.  
  520.       if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB))
  521.         inVerbatim = FALSE;
  522.  
  523.       break;
  524.     }
  525.     case CHUNK_TYPE_ARG:
  526.     {
  527.       wxNode *node = chunk->children.First();
  528.       while (node)
  529.       {
  530.         TexChunk *child_chunk = (TexChunk *)node->Data();
  531.         Text2RTF(child_chunk);
  532.         node = node->Next();
  533.       }
  534.  
  535.       break;
  536.     }
  537.     case CHUNK_TYPE_STRING:
  538.     {
  539.       if (chunk->value)
  540.         ProcessText2RTF(chunk);
  541.       break;
  542.     }
  543.   }
  544. }
  545.  
  546. /*
  547.  * Not used yet
  548.  *
  549.  */
  550.  
  551. char browseBuf[10];
  552. static long browseId = 0;
  553. char *GetBrowseString(void)
  554. {
  555.   char buf[10];
  556.   browseId ++;
  557.   sprintf(buf, "%ld", browseId);
  558.   int noZeroes = 5-strlen(buf);
  559.   strcpy(browseBuf, "browse");
  560.   for (int i = 0; i < noZeroes; i++)
  561.     strcat(browseBuf, "0");
  562.   strcat(browseBuf, buf);
  563.   return browseBuf;
  564. }
  565.  
  566. /*
  567.  * Keeping track of environments to restore the styles after \pard.
  568.  * Push strings like "\qc" onto stack.
  569.  *
  570.  */
  571.  
  572. void PushEnvironmentStyle(char *style)
  573. {
  574.   environmentStack.Add(style);
  575. }
  576.  
  577. void PopEnvironmentStyle(void)
  578. {
  579.   wxNode *node = environmentStack.Last();
  580.   if (node)
  581.   {
  582.     char *val = (char *)node->Data();
  583.     delete[] val;
  584.     delete node;
  585.   }
  586. }
  587.  
  588. // Write out the styles, most recent first.
  589. void WriteEnvironmentStyles(void)
  590. {
  591.   wxNode *node = environmentStack.Last();
  592.   while (node)
  593.   {
  594.     char *val = (char *)node->Data();
  595.     TexOutput(val);
  596.     node = node->Next();
  597.   }
  598.   if (!inTabular && (ParIndent > 0) && (forbidParindent == 0))
  599.   {
  600.     char buf[15];
  601.     sprintf(buf, "\\fi%d", ParIndent*20); // Convert points to TWIPS
  602.     TexOutput(buf);
  603.   }
  604.   if (environmentStack.Number() > 0 || (ParIndent > 0))
  605.     TexOutput("\n");
  606. }
  607.  
  608. /*
  609.  * Parse table argument
  610.  *
  611.  */
  612.  
  613. Bool ParseTableArgument(char *value)
  614. {
  615.   noColumns = 0;
  616.   int i = 0;
  617.   int len = strlen(value);
  618.   Bool isBorder = FALSE;
  619.   while (i < len)
  620.   {
  621.     int ch = value[i];
  622.     if (ch == '|')
  623.     {
  624.       i ++;
  625.       isBorder = TRUE;
  626.     }
  627.     else if (ch == 'l')
  628.     {
  629.       TableData[noColumns].leftBorder = isBorder;
  630.       TableData[noColumns].rightBorder = FALSE;
  631.       TableData[noColumns].justification = 'l';
  632.       TableData[noColumns].width = 2000; // Estimate
  633. //      TableData[noColumns].spacing = ??
  634.       noColumns ++;
  635.       i ++;
  636.       isBorder = FALSE;
  637.     }
  638.     else if (ch == 'c')
  639.     {
  640.       TableData[noColumns].leftBorder = isBorder;
  641.       TableData[noColumns].rightBorder = FALSE;
  642.       TableData[noColumns].justification = 'c';
  643.       TableData[noColumns].width = defaultTableColumnWidth; // Estimate
  644. //      TableData[noColumns].spacing = ??
  645.       noColumns ++;
  646.       i ++;
  647.       isBorder = FALSE;
  648.     }
  649.     else if (ch == 'r')
  650.     {
  651.       TableData[noColumns].leftBorder = isBorder;
  652.       TableData[noColumns].rightBorder = FALSE;
  653.       TableData[noColumns].justification = 'r';
  654.       TableData[noColumns].width = 2000; // Estimate
  655. //      TableData[noColumns].spacing = ??
  656.       noColumns ++;
  657.       i ++;
  658.       isBorder = FALSE;
  659.     }
  660.     else if (ch == 'p')
  661.     {
  662.       i ++;
  663.       int j = 0;
  664.       char numberBuf[50];
  665.       ch = value[i];
  666.       if (ch == '{')
  667.       {
  668.         i++;
  669.         ch = value[i];
  670.       }
  671.         
  672.       while ((i < len) && (isdigit(ch) || ch == '.'))
  673.       {
  674.         numberBuf[j] = ch;
  675.         j ++;
  676.         i ++;
  677.         ch = value[i];
  678.       }
  679.       // Assume we have 2 characters for units
  680.       numberBuf[j] = value[i];
  681.       j ++; i++;
  682.       numberBuf[j] = value[i];
  683.       j ++; i++;
  684.       numberBuf[j] = 0;
  685.       if (value[i] == '}') i++;
  686.       
  687.       TableData[noColumns].leftBorder = isBorder;
  688.       TableData[noColumns].rightBorder = FALSE;
  689.       TableData[noColumns].justification = 'r';
  690.       TableData[noColumns].width = 20*ParseUnitArgument(numberBuf);
  691. //      TableData[noColumns].spacing = ??
  692.       noColumns ++;
  693.       isBorder = FALSE;
  694.     }
  695.     else
  696.     {
  697.       char *buf = new char[strlen(value) + 80];
  698.       sprintf(buf, "Tabular first argument \"%s\" too complex!", value);
  699.       OnError(buf);
  700.       delete[] buf;
  701.       return FALSE;
  702.     }
  703.   }
  704.   if (isBorder)
  705.     TableData[noColumns-1].rightBorder = TRUE;
  706.   return TRUE;
  707. }
  708.  
  709. /*
  710.  * Output a header
  711.  *
  712.  */
  713.  
  714. void OutputRTFHeaderCommands(void)
  715. {
  716.   char buf[300];
  717.   if (PageStyle && strcmp(PageStyle, "plain") == 0)
  718.   {
  719.     TexOutput("{\\headerl }{\\headerr }");
  720.   }
  721.   else if (PageStyle && strcmp(PageStyle, "empty") == 0)
  722.   {
  723.     TexOutput("{\\headerl }{\\headerr }");
  724.   }
  725.   else if (PageStyle && strcmp(PageStyle, "headings") == 0)
  726.   {
  727.     // Left header
  728.     TexOutput("{\\headerl\\fi0 ");
  729.  
  730.     if (headerRule)
  731.       TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
  732.  
  733.     TexOutput("{\\i \\qr ");
  734.     if (DocumentStyle == LATEX_ARTICLE)
  735.     {
  736.       sprintf(buf, "SECTION %d", sectionNo);
  737.       TexOutput(buf);
  738.     }
  739.     else
  740.     {
  741.       sprintf(buf, "CHAPTER %d: ", chapterNo);
  742.       TexOutput(buf);
  743.     }
  744.     TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  745.     TexOutput("}\\par\\pard}");
  746.  
  747.     // Right header
  748.     TexOutput("{\\headerr\\fi0 ");
  749.  
  750.     if (headerRule)
  751.       TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
  752.  
  753.     TexOutput("{\\i \\qc ");
  754.     if (DocumentStyle == LATEX_ARTICLE)
  755.     {
  756.       sprintf(buf, "SECTION %d", sectionNo);
  757.       TexOutput(buf);
  758.     }
  759.     else
  760.     {
  761.       sprintf(buf, "CHAPTER %d", chapterNo);
  762.       TexOutput(buf);
  763.     }
  764.     TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  765.     TexOutput("}\\par\\pard}");
  766.   }
  767.   else
  768.   {
  769.     if (LeftHeaderEven || CentreHeaderEven || RightHeaderEven)
  770.     {
  771.       TexOutput("{\\headerl\\fi0 ");
  772.  
  773.       if (headerRule)
  774.         TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
  775.  
  776.       if (LeftHeaderEven)
  777.       {
  778.         if (!CentreHeaderEven && !RightHeaderEven)
  779.           TexOutput("\\ql ");
  780.         TraverseChildrenFromChunk(LeftHeaderEven);
  781.       }
  782.       if (CentreHeaderEven)
  783.       {
  784.         if (!LeftHeaderEven && !RightHeaderEven)
  785.           TexOutput("\\qc ");
  786.         else
  787.           TexOutput("\\tab\\tab\\tab ");
  788.         TraverseChildrenFromChunk(CentreHeaderEven);
  789.       }
  790.       if (RightHeaderEven)
  791.       {
  792.         if (!LeftHeaderEven && !CentreHeaderEven)
  793.           TexOutput("\\qr ");
  794.         else
  795.           TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
  796.         TraverseChildrenFromChunk(RightHeaderEven);
  797.       }
  798.       TexOutput("\\par\\pard}");
  799.     }
  800.  
  801.     if (LeftHeaderOdd || CentreHeaderOdd || RightHeaderOdd)
  802.     {
  803.       TexOutput("{\\headerr\\fi0 ");
  804.  
  805.       if (headerRule)
  806.         TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
  807.  
  808.       if (LeftHeaderOdd)
  809.       {
  810.         if (!CentreHeaderOdd && !RightHeaderOdd)
  811.           TexOutput("\\ql ");
  812.         TraverseChildrenFromChunk(LeftHeaderOdd);
  813.       }
  814.       if (CentreHeaderOdd)
  815.       {
  816.         if (!LeftHeaderOdd && !RightHeaderOdd)
  817.           TexOutput("\\qc ");
  818.         else
  819.           TexOutput("\\tab\\tab\\tab ");
  820.         TraverseChildrenFromChunk(CentreHeaderOdd);
  821.       }
  822.       if (RightHeaderOdd)
  823.       {
  824.         if (!LeftHeaderOdd && !CentreHeaderOdd)
  825.           TexOutput("\\qr ");
  826.         else
  827.           TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
  828.         TraverseChildrenFromChunk(RightHeaderOdd);
  829.       }
  830.       TexOutput("\\par\\pard}");
  831.     }
  832.     // As an approximation, don't put a header on the first page of a section.
  833.     // This may not always be desired, but it's a reasonable guess.
  834.     TexOutput("{\\headerf }");
  835.   }
  836. }
  837.  
  838. void OutputRTFFooterCommands(void)
  839. {
  840.   if (PageStyle && strcmp(PageStyle, "plain") == 0)
  841.   {
  842.     TexOutput("{\\footerl\\fi0 ");
  843.     if (footerRule)
  844.       TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
  845.     TexOutput("{\\qc ");
  846.     TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  847.     TexOutput("}\\par\\pard}");
  848.  
  849.     TexOutput("{\\footerr\\fi0 ");
  850.     if (footerRule)
  851.       TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
  852.     TexOutput("{\\qc ");
  853.     TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  854.     TexOutput("}\\par\\pard}");
  855.   }
  856.   else if (PageStyle && strcmp(PageStyle, "empty") == 0)
  857.   {
  858.     TexOutput("{\\footerl }{\\footerr }");
  859.   }
  860.   else if (PageStyle && strcmp(PageStyle, "headings") == 0)
  861.   {
  862.     TexOutput("{\\footerl }{\\footerr }");
  863.   }
  864.   else
  865.   {
  866.     if (LeftFooterEven || CentreFooterEven || RightFooterEven)
  867.     {
  868.       TexOutput("{\\footerl\\fi0 ");
  869.       if (footerRule)
  870.         TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
  871.       if (LeftFooterEven)
  872.       {
  873.         if (!CentreFooterEven && !RightFooterEven)
  874.           TexOutput("\\ql ");
  875.         TraverseChildrenFromChunk(LeftFooterEven);
  876.       }
  877.       if (CentreFooterEven)
  878.       {
  879.         if (!LeftFooterEven && !RightFooterEven)
  880.           TexOutput("\\qc ");
  881.         else
  882.           TexOutput("\\tab\\tab\\tab ");
  883.         TraverseChildrenFromChunk(CentreFooterEven);
  884.       }
  885.       if (RightFooterEven)
  886.       {
  887.         if (!LeftFooterEven && !CentreFooterEven)
  888.           TexOutput("\\qr ");
  889.         else
  890.           TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
  891.         TraverseChildrenFromChunk(RightFooterEven);
  892.       }
  893.       TexOutput("\\par\\pard}");
  894.     }
  895.  
  896.     if (LeftFooterOdd || CentreFooterOdd || RightFooterOdd)
  897.     {
  898.       TexOutput("{\\footerr\\fi0 ");
  899.       if (footerRule)
  900.         TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
  901.       if (LeftFooterOdd)
  902.       {
  903.         if (!CentreFooterOdd && !RightFooterOdd)
  904.           TexOutput("\\ql ");
  905.         TraverseChildrenFromChunk(LeftFooterOdd);
  906.       }
  907.       if (CentreFooterOdd)
  908.       {
  909.         if (!LeftFooterOdd && !RightFooterOdd)
  910.           TexOutput("\\qc ");
  911.         else
  912.           TexOutput("\\tab\\tab\\tab ");
  913.         TraverseChildrenFromChunk(CentreFooterOdd);
  914.       }
  915.       if (RightFooterOdd)
  916.       {
  917.         if (!LeftFooterOdd && !CentreFooterOdd)
  918.           TexOutput("\\qr ");
  919.         else
  920.           TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
  921.         TraverseChildrenFromChunk(RightFooterOdd);
  922.       }
  923.       TexOutput("\\par\\pard}");
  924.     }
  925.  
  926.     // As an approximation, put a footer on the first page of a section.
  927.     // This may not always be desired, but it's a reasonable guess.
  928.     if (LeftFooterOdd || CentreFooterOdd || RightFooterOdd)
  929.     {
  930.       TexOutput("{\\footerf\\fi0 ");
  931.       if (LeftFooterOdd)
  932.       {
  933.         if (!CentreFooterOdd && !RightFooterOdd)
  934.           TexOutput("\\ql ");
  935.         TraverseChildrenFromChunk(LeftFooterOdd);
  936.       }
  937.       if (CentreFooterOdd)
  938.       {
  939.         if (!LeftFooterOdd && !RightFooterOdd)
  940.           TexOutput("\\qc ");
  941.         else
  942.           TexOutput("\\tab\\tab\\tab ");
  943.         TraverseChildrenFromChunk(CentreFooterOdd);
  944.       }
  945.       if (RightFooterOdd)
  946.       {
  947.         if (!LeftFooterOdd && !CentreFooterOdd)
  948.           TexOutput("\\qr ");
  949.         else
  950.           TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
  951.         TraverseChildrenFromChunk(RightFooterOdd);
  952.       }
  953.       TexOutput("\\par\\pard}");
  954.     }
  955.   }
  956. }
  957.  
  958. // Called on start/end of macro examination
  959. void RTFOnMacro(int macroId, int no_args, Bool start)
  960. {
  961.   // ltLABEL is included here because after a section but BEFORE
  962.   // the label is seen, a new paragraph is issued. Don't upset this by
  963.   // immediately forgetting we've done it.
  964.   if (start && (macroId != ltPAR && macroId != ltITEMIZE &&
  965.                         macroId != ltENUMERATE && macroId != ltDESCRIPTION &&
  966.                         macroId != ltVERBATIM && macroId != ltLABEL &&
  967.                         macroId != ltSETHEADER && macroId != ltSETFOOTER &&
  968.                         macroId != ltPAGENUMBERING &&
  969.                         (forbidResetPar == 0)))
  970.   {
  971.     issuedNewParagraph = FALSE;
  972.   }
  973.  
  974.   char buf[300];
  975.   switch (macroId)
  976.   {
  977.   case ltCHAPTER:
  978.   case ltCHAPTERSTAR:
  979.   case ltCHAPTERHEADING:
  980.   case ltCHAPTERHEADINGSTAR:
  981.   {
  982.     if (!start)
  983.     {
  984.       sectionNo = 0;
  985.       figureNo = 0;
  986.       tableNo = 0;
  987.       subsectionNo = 0;
  988.       subsubsectionNo = 0;
  989.       footnoteCount = 0;
  990.  
  991.       if (macroId != ltCHAPTERSTAR && macroId != ltCHAPTERHEADINGSTAR)
  992.         chapterNo ++;
  993.  
  994.       char *topicName = FindTopicName(GetNextChunk());
  995.       SetCurrentChapterName(topicName);
  996.       AddTexRef(topicName, NULL, ChapterNameString, chapterNo);
  997.  
  998.       if (winHelp)
  999.       {
  1000.         fprintf(Contents, "\n{\\uldb ");
  1001.         fprintf(Chapters, "\\page");
  1002.         fprintf(Chapters, "\n${\\footnote ");
  1003.         SetCurrentOutputs(Contents, Chapters);
  1004.       }
  1005.       else
  1006.       {
  1007.         fprintf(Chapters, "\\sect\\pgncont\\titlepg\n");
  1008.  
  1009.         // If a non-custom page style, we generate the header now.
  1010.         if (PageStyle && (strcmp(PageStyle, "plain") == 0 ||
  1011.                           strcmp(PageStyle, "empty") == 0 ||
  1012.                           strcmp(PageStyle, "headings") == 0))
  1013.         {
  1014.           OutputRTFHeaderCommands();
  1015.           OutputRTFFooterCommands();
  1016.         }
  1017.         
  1018.         // Need to reset the current numbering style, or RTF forgets it.
  1019.         SetCurrentOutput(Chapters);
  1020.         OutputNumberStyle(currentNumberStyle);
  1021.  
  1022.         SetCurrentOutput(Contents);
  1023.  
  1024.         if (macroId == ltCHAPTER)
  1025.         {
  1026.           // Section
  1027.           fprintf(Contents, "\\par\n\\pard{\\b %d\\tab ", chapterNo);
  1028.         }
  1029.         else if (macroId == ltCHAPTERHEADING)
  1030.         {
  1031.           fprintf(Contents, "\\par\n\\pard{\\b ");
  1032.         }
  1033.         else SetCurrentOutput(NULL); // No entry in table of contents
  1034.       }
  1035.   
  1036.       startedSections = TRUE;
  1037.  
  1038.       // Output heading to contents page
  1039.       OutputCurrentSection();
  1040.       
  1041.       if (winHelp)
  1042.         fprintf(Contents, "}{\\v %s}\\par\\pard\n", topicName);
  1043.       else if ((macroId == ltCHAPTER) || (macroId == ltCHAPTERHEADING))
  1044.         fprintf(Contents, "}\\par\\par\\pard\n");
  1045.  
  1046.       // From here, just output to chapter
  1047.       SetCurrentOutput(Chapters);
  1048.  
  1049.       if (winHelp)
  1050.       {
  1051.         fprintf(Chapters, "}\n#{\\footnote %s}\n", topicName);
  1052.         fprintf(Chapters, "+{\\footnote %s}\n", GetBrowseString());
  1053.         fprintf(Chapters, "K{\\footnote ");
  1054.         OutputCurrentSection();
  1055.         fprintf(Chapters, "}\n");
  1056.         GenerateKeywordsForTopic(topicName);
  1057.         if (useUpButton)
  1058.         {
  1059.           fprintf(Chapters, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  1060.                FileNameFromPath(FileRoot), "Contents");
  1061.         }
  1062.       }
  1063.  
  1064.       char *styleCommand = "";
  1065.       if (!winHelp && useHeadingStyles && (macroId == ltCHAPTER || macroId == ltCHAPTERHEADING || macroId == ltCHAPTERHEADINGSTAR))
  1066.         styleCommand = "\\s1";
  1067.       fprintf(Chapters, "\\pard{%s", (winHelp ? "\\keepn" : styleCommand));
  1068.       WriteHeadingStyle(Chapters, 1);  fprintf(Chapters, " ");
  1069.       if (!winHelp)
  1070.       {
  1071.         if (macroId == ltCHAPTER)
  1072.           fprintf(Chapters, "{\\bkmkstart %s}%d{\\bkmkend %s}. ", topicName, chapterNo,
  1073.                  topicName);
  1074.       }
  1075.       OutputCurrentSection();
  1076.       TexOutput("\\par\\pard}\\par\n");
  1077.       issuedNewParagraph = TRUE;
  1078.     }
  1079.     break;
  1080.   }
  1081.   case ltSECTION:
  1082.   case ltSECTIONSTAR:
  1083.   case ltSECTIONHEADING:
  1084.   case ltSECTIONHEADINGSTAR:
  1085.   case ltGLOSS:
  1086.   {
  1087.     FILE *jumpFrom;
  1088.     if (DocumentStyle == LATEX_ARTICLE)
  1089.       jumpFrom = Contents;
  1090.     else
  1091.       jumpFrom = Chapters;
  1092.  
  1093.     if (!start)
  1094.     {
  1095.       subsectionNo = 0;
  1096.       subsubsectionNo = 0;
  1097.       if (DocumentStyle == LATEX_ARTICLE)
  1098.         footnoteCount = 0;
  1099.  
  1100.       if (macroId != ltSECTIONSTAR && macroId != ltSECTIONHEADINGSTAR)
  1101.         sectionNo ++;
  1102.  
  1103.       char *topicName = FindTopicName(GetNextChunk());
  1104.       SetCurrentSectionName(topicName);
  1105.       AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo);
  1106.  
  1107.       if (winHelp)
  1108.       {
  1109.         SetCurrentOutputs(jumpFrom, Sections);
  1110.         // Newline for a new section if this is an article
  1111.         if ((DocumentStyle == LATEX_ARTICLE) &&
  1112.             ((macroId == ltSECTION) || (macroId == ltSECTIONSTAR) || (macroId == ltSECTIONHEADINGSTAR)))
  1113.           fprintf(Sections, "\\page\n");
  1114.  
  1115.         fprintf(jumpFrom, "\n{\\uldb ");
  1116.       }
  1117.       else
  1118.       {
  1119.         if (DocumentStyle == LATEX_ARTICLE)
  1120.         {
  1121.           TexOutput("\\sect\\pgncont\n");
  1122.           // If a non-custom page style, we generate the header now.
  1123.           if (PageStyle && (strcmp(PageStyle, "plain") == 0 ||
  1124.                             strcmp(PageStyle, "empty") == 0 ||
  1125.                             strcmp(PageStyle, "headings") == 0))
  1126.           {
  1127.             OutputRTFHeaderCommands();
  1128.             OutputRTFFooterCommands();
  1129.           }
  1130.         }
  1131.         SetCurrentOutput(Contents);
  1132.  
  1133.         if (macroId == ltSECTION)
  1134.         {
  1135.           if (DocumentStyle == LATEX_REPORT)
  1136.             fprintf(Contents, "\n\\pard{\\tab %d.%d\\tab ", chapterNo, sectionNo);
  1137.           else
  1138.             fprintf(Contents, "\\par\n\\pard{\\b %d\\tab ", sectionNo);
  1139.         }
  1140.         else if (macroId == ltSECTIONHEADING)
  1141.         {
  1142.           if (DocumentStyle == LATEX_REPORT)
  1143.             fprintf(Contents, "\n\\pard{\\tab ", chapterNo, sectionNo);
  1144.           else
  1145.             fprintf(Contents, "\\par\n\\pard{\\b ", sectionNo);
  1146.         }
  1147.         else SetCurrentOutput(NULL);
  1148.       } 
  1149.  
  1150.       if (startedSections)
  1151.       {
  1152.         if (winHelp)
  1153.           fprintf(Sections, "\\page\n");
  1154.       }
  1155.       startedSections = TRUE;
  1156.  
  1157.       if (winHelp)
  1158.         fprintf(Sections, "\n${\\footnote ");
  1159.  
  1160.       // Output heading to contents page
  1161.       OutputCurrentSection();
  1162.  
  1163.       if (winHelp)
  1164.         fprintf(jumpFrom, "}{\\v %s}\\par\\pard\n", topicName);
  1165.       else if ((macroId != ltSECTIONSTAR) && (macroId != ltGLOSS))
  1166.       {
  1167.         if (DocumentStyle == LATEX_REPORT)
  1168.           fprintf(Contents, "}\\par\\pard\n");
  1169.         else
  1170.           fprintf(Contents, "}\\par\\par\\pard\n");
  1171.       }
  1172.         
  1173.       SetCurrentOutput(winHelp ? Sections : Chapters);
  1174.  
  1175.       if (winHelp)
  1176.       {
  1177.         fprintf(Sections, "}\n#{\\footnote %s}\n", topicName);
  1178.         fprintf(Sections, "+{\\footnote %s}\n", GetBrowseString());
  1179.         fprintf(Sections, "K{\\footnote ");
  1180.         OutputCurrentSection();
  1181.         fprintf(Sections, "}\n");
  1182.         GenerateKeywordsForTopic(topicName);
  1183.         if (useUpButton)
  1184.         {
  1185.           if (DocumentStyle == LATEX_ARTICLE)
  1186.           {
  1187.             fprintf(Sections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  1188.                FileNameFromPath(FileRoot), "Contents");
  1189.           }
  1190.           else if (CurrentChapterName)
  1191.           {
  1192.             fprintf(Sections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  1193.                FileNameFromPath(FileRoot), CurrentChapterName);
  1194.           }
  1195.         }
  1196.       }
  1197.  
  1198.       char *styleCommand = "";
  1199.       if (!winHelp && useHeadingStyles && (macroId != ltSECTIONSTAR))
  1200.       {
  1201.         if (DocumentStyle == LATEX_ARTICLE)
  1202.           styleCommand = "\\s1";
  1203.         else
  1204.           styleCommand = "\\s2";
  1205.       }
  1206.       char *keep = "";
  1207.       if (winHelp && (macroId != ltGLOSS))
  1208.         keep = "\\keepn";
  1209.         
  1210.       fprintf(winHelp ? Sections : Chapters, "\\pard{%s%s",
  1211.          keep, styleCommand);
  1212.  
  1213.       WriteHeadingStyle((winHelp ? Sections : Chapters),
  1214.                         (DocumentStyle == LATEX_ARTICLE ? 1 : 2));
  1215.       fprintf(winHelp ? Sections : Chapters, " ");
  1216.  
  1217.       if (!winHelp)
  1218.       {
  1219.         if ((macroId != ltSECTIONSTAR) && (macroId != ltSECTIONHEADINGSTAR) && (macroId != ltGLOSS))
  1220.         {
  1221.           if (DocumentStyle == LATEX_REPORT)
  1222.             fprintf(Chapters, "{\\bkmkstart %s}%d.%d{\\bkmkend %s}. ", topicName, chapterNo, sectionNo,
  1223.                 topicName);
  1224.           else
  1225.             fprintf(Chapters, "{\\bkmkstart %s}%d{\\bkmkend %s}. ", topicName, sectionNo,
  1226.                 topicName);
  1227.         }
  1228.       }
  1229.       OutputCurrentSection();
  1230.       TexOutput("\\par\\pard}\\par\n");
  1231.       issuedNewParagraph = TRUE;
  1232.     }
  1233.     break;
  1234.   }
  1235.   case ltSUBSECTION:
  1236.   case ltSUBSECTIONSTAR:
  1237.   case ltMEMBERSECTION:
  1238.   case ltFUNCTIONSECTION:
  1239.   {
  1240.     if (!start)
  1241.     {
  1242.       subsubsectionNo = 0;
  1243.  
  1244.       if (macroId != ltSUBSECTIONSTAR)
  1245.         subsectionNo ++;
  1246.  
  1247.       char *topicName = FindTopicName(GetNextChunk());
  1248.       SetCurrentSubsectionName(topicName);
  1249.       AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo, subsectionNo);
  1250.  
  1251.       if (winHelp)
  1252.       {
  1253.         SetCurrentOutputs(Sections, Subsections);
  1254.         SetCurrentOutputs(Sections, Subsections);
  1255.         fprintf(Sections, "\n{\\uldb ");
  1256.       }
  1257.       else
  1258.       {
  1259.         if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
  1260.             (macroId != ltFUNCTIONSECTION))
  1261.         {
  1262.           SetCurrentOutput(Contents);
  1263.           if (DocumentStyle == LATEX_REPORT)
  1264.             fprintf(Contents, "\n\\pard\\tab\\tab %d.%d.%d\\tab ", chapterNo, sectionNo, subsectionNo);
  1265.           else
  1266.             fprintf(Contents, "\n\\pard\\tab %d.%d\\tab ", sectionNo, subsectionNo);
  1267.         } else SetCurrentOutput(NULL);
  1268.       }
  1269.       if (startedSections)
  1270.       {
  1271.         if (winHelp)
  1272.           fprintf(Subsections, "\\page\n");
  1273.         else
  1274.           fprintf(Chapters, "\\par\n");
  1275.       }
  1276.       startedSections = TRUE;
  1277.  
  1278.       if (winHelp)
  1279.         fprintf(Subsections, "\n${\\footnote ");
  1280.  
  1281.       // Output to contents page
  1282.       OutputCurrentSection();
  1283.  
  1284.       if (winHelp)
  1285.         fprintf(Sections, "}{\\v %s}\\par\\pard\n", topicName);
  1286.       else if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
  1287.          (macroId != ltFUNCTIONSECTION))
  1288.         fprintf(Contents, "\\par\\pard\n");
  1289.  
  1290.       SetCurrentOutput(winHelp ? Subsections : Chapters);
  1291.       if (winHelp)
  1292.       {
  1293.         fprintf(Subsections, "}\n#{\\footnote %s}\n", topicName);
  1294.         fprintf(Subsections, "+{\\footnote %s}\n", GetBrowseString());
  1295.         fprintf(Subsections, "K{\\footnote ");
  1296.         OutputCurrentSection();
  1297.         fprintf(Subsections, "}\n");
  1298.         GenerateKeywordsForTopic(topicName);
  1299.         if (useUpButton && CurrentSectionName)
  1300.         {
  1301.           fprintf(Subsections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  1302.              FileNameFromPath(FileRoot), CurrentSectionName);
  1303.         }
  1304.       }
  1305.       if (!winHelp && indexSubsections)
  1306.       {
  1307.         // Insert index entry for this subsection
  1308.         TexOutput("{\\xe\\v {");
  1309.         OutputCurrentSection();
  1310.         TexOutput("}}");
  1311.       }
  1312.  
  1313.       char *styleCommand = "";
  1314.       if (!winHelp && useHeadingStyles && (macroId != ltSUBSECTIONSTAR))
  1315.       {
  1316.         if (DocumentStyle == LATEX_ARTICLE)
  1317.           styleCommand = "\\s2";
  1318.         else
  1319.           styleCommand = "\\s3";
  1320.       }
  1321.       char *keep = "";
  1322.       if (winHelp)
  1323.         keep = "\\keepn";
  1324.  
  1325.       fprintf(winHelp ? Subsections : Chapters, "\\pard{%s%s",
  1326.          keep, styleCommand);
  1327.  
  1328.       WriteHeadingStyle((winHelp ? Subsections : Chapters),
  1329.                         (DocumentStyle == LATEX_ARTICLE ? 2 : 3));
  1330.       fprintf(winHelp ? Subsections : Chapters, " ");
  1331.  
  1332.       if (!winHelp &&
  1333.          (macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
  1334.          (macroId != ltFUNCTIONSECTION))
  1335.       {
  1336.         if (DocumentStyle == LATEX_REPORT)
  1337.           fprintf(Chapters, "{\\bkmkstart %s}%d.%d.%d{\\bkmkend %s}. ", topicName, chapterNo, sectionNo, subsectionNo,
  1338.                    topicName);
  1339.         else
  1340.           fprintf(Chapters, "{\\bkmkstart %s}%d.%d{\\bkmkend %s}. ", topicName, sectionNo, subsectionNo,
  1341.                    topicName);
  1342.       }
  1343.       OutputCurrentSection(); // Repeat section header
  1344.       TexOutput("\\par\\pard}\\par\n");
  1345.       issuedNewParagraph = TRUE;
  1346. //      if (winHelp) TexOutput("\\pard");
  1347.     }
  1348.     break;
  1349.   }
  1350.   case ltSUBSUBSECTION:
  1351.   case ltSUBSUBSECTIONSTAR:
  1352.   {
  1353.     if (!start)
  1354.     {
  1355.       if (macroId != ltSUBSUBSECTIONSTAR)
  1356.         subsubsectionNo ++;
  1357.  
  1358.       char *topicName = FindTopicName(GetNextChunk());
  1359.       SetCurrentTopic(topicName);
  1360.       AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo, subsectionNo, subsubsectionNo);
  1361.  
  1362.       if (winHelp)
  1363.       {
  1364.         SetCurrentOutputs(Subsections, Subsubsections);
  1365.         fprintf(Subsections, "\n{\\uldb ");
  1366.       }
  1367.       else
  1368.       {
  1369.         if (macroId != ltSUBSUBSECTIONSTAR)
  1370.         {
  1371.           if (DocumentStyle == LATEX_ARTICLE)
  1372.           {
  1373.             SetCurrentOutput(Contents);
  1374.             fprintf(Contents, "\n\\tab\\tab %d.%d.%d\\tab ",
  1375.                                sectionNo, subsectionNo, subsubsectionNo);
  1376.           }
  1377.           else
  1378.             SetCurrentOutput(NULL); // Don't write it into the contents, or anywhere else
  1379.     }
  1380.         else
  1381.           SetCurrentOutput(NULL); // Don't write it into the contents, or anywhere else
  1382.       }
  1383.       
  1384.       if (startedSections)
  1385.       {
  1386.         if (winHelp)
  1387.           fprintf(Subsubsections, "\\page\n");
  1388.         else
  1389.           fprintf(Chapters, "\\par\n");
  1390.       }
  1391.  
  1392.       startedSections = TRUE;
  1393.  
  1394.       if (winHelp)
  1395.         fprintf(Subsubsections, "\n${\\footnote ");
  1396.  
  1397.       // Output header to contents page
  1398.       OutputCurrentSection();
  1399.  
  1400.       if (winHelp)
  1401.         fprintf(Subsections, "}{\\v %s}\\par\\pard\n", topicName);
  1402.       else if ((DocumentStyle == LATEX_ARTICLE) && (macroId != ltSUBSUBSECTIONSTAR))
  1403.         fprintf(Contents, "\\par\\pard\n");
  1404.         
  1405.       SetCurrentOutput(winHelp ? Subsubsections : Chapters);
  1406.       if (winHelp)
  1407.       {
  1408.         fprintf(Subsubsections, "}\n#{\\footnote %s}\n", topicName);
  1409.         fprintf(Subsubsections, "+{\\footnote %s}\n", GetBrowseString());
  1410.         fprintf(Subsubsections, "K{\\footnote ");
  1411.         OutputCurrentSection();
  1412.         fprintf(Subsubsections, "}\n");
  1413.         GenerateKeywordsForTopic(topicName);
  1414.         if (useUpButton && CurrentSubsectionName)
  1415.         {
  1416.           fprintf(Subsubsections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  1417.              FileNameFromPath(FileRoot), CurrentSubsectionName);
  1418.         }
  1419.       }
  1420.       if (!winHelp && indexSubsections)
  1421.       {
  1422.         // Insert index entry for this subsubsection
  1423.         TexOutput("{\\xe\\v {");
  1424.         OutputCurrentSection();
  1425.         TexOutput("}}");
  1426.       }
  1427.  
  1428.       char *styleCommand = "";
  1429.       if (!winHelp && useHeadingStyles && (macroId != ltSUBSUBSECTIONSTAR))
  1430.       {
  1431.         if (DocumentStyle == LATEX_ARTICLE)
  1432.           styleCommand = "\\s3";
  1433.         else
  1434.           styleCommand = "\\s4";
  1435.       }
  1436.       char *keep = "";
  1437.       if (winHelp)
  1438.         keep = "\\keepn";
  1439.  
  1440.       fprintf(winHelp ? Subsubsections : Chapters, "\\pard{%s%s",
  1441.          keep, styleCommand);
  1442.  
  1443.       WriteHeadingStyle((winHelp ? Subsubsections : Chapters),
  1444.                         (DocumentStyle == LATEX_ARTICLE ? 3 : 4));
  1445.       fprintf(winHelp ? Subsubsections : Chapters, " ");
  1446.          
  1447.       if (!winHelp && (macroId != ltSUBSUBSECTIONSTAR))
  1448.       {
  1449.         if (DocumentStyle == LATEX_ARTICLE)
  1450.           fprintf(Chapters, "{\\bkmkstart %s}%d.%d.%d{\\bkmkend %s}. ", topicName, sectionNo, subsectionNo, subsubsectionNo,
  1451.                   topicName);
  1452.         else
  1453.           fprintf(Chapters, "{\\bkmkstart %s}%d.%d.%d.%d{\\bkmkend %s}. ", topicName, chapterNo, sectionNo, subsectionNo, subsubsectionNo,
  1454.                   topicName);
  1455.       }      
  1456.       OutputCurrentSection(); // Repeat section header
  1457.       TexOutput("\\par\\pard}\\par\n");
  1458.       issuedNewParagraph = TRUE;
  1459. //      if (winHelp) TexOutput("\\pard");
  1460.     }
  1461.     break;
  1462.   }
  1463.   case ltCAPTION:
  1464.   case ltCAPTIONSTAR:
  1465.   {
  1466.     if (!start)
  1467.     {
  1468.       char *topicName = FindTopicName(GetNextChunk());
  1469.  
  1470.       TexOutput("\\pard\\par");
  1471.       char figBuf[200];
  1472.  
  1473.       if (inFigure)
  1474.       {
  1475.         figureNo ++;
  1476.  
  1477.         if (winHelp || !useWord)
  1478.         {
  1479.           if (DocumentStyle != LATEX_ARTICLE)
  1480.             sprintf(figBuf, "%s %d.%d: ", FigureNameString, chapterNo, figureNo);
  1481.           else
  1482.             sprintf(figBuf, "%s %d: ", FigureNameString, figureNo);
  1483.         }
  1484.         else
  1485.         {
  1486.           sprintf(figBuf, "%s {\\field\\flddirty{\\*\\fldinst  SEQ Figure \\\\* ARABIC }{\\fldrslt {\\bkmkstart %s}??{\\bkmkend %s}}}: ",
  1487.                FigureNameString, topicName, topicName);
  1488.         }
  1489.       }
  1490.       else
  1491.       {
  1492.         tableNo ++;
  1493.  
  1494.         if (winHelp || !useWord)
  1495.         {
  1496.           if (DocumentStyle != LATEX_ARTICLE)
  1497.             sprintf(figBuf, "%s %d.%d: ", TableNameString, chapterNo, figureNo);
  1498.           else
  1499.             sprintf(figBuf, "%s %d: ", TableNameString, tableNo);
  1500.         }
  1501.         else
  1502.         {
  1503.           sprintf(figBuf, "%s {\\field\\flddirty{\\*\\fldinst  SEQ Table \\\\* ARABIC }{\\fldrslt {\\bkmkstart %s}??{\\bkmkend %s}}}: ",
  1504.                TableNameString, topicName, topicName);
  1505.         }
  1506.       }
  1507.  
  1508.       int n = (inTable ? tableNo : figureNo);
  1509.       AddTexRef(topicName, NULL, NULL,
  1510.            ((DocumentStyle != LATEX_ARTICLE) ? chapterNo : n),
  1511.             ((DocumentStyle != LATEX_ARTICLE) ? n : 0));
  1512.  
  1513.       if (winHelp)
  1514.         TexOutput("\\qc{\\b ");
  1515.       else
  1516.         TexOutput("\\ql{\\b ");
  1517.       TexOutput(figBuf);
  1518.  
  1519.       OutputCurrentSection();
  1520.  
  1521.       TexOutput("}\\par\\pard\n");
  1522.       WriteEnvironmentStyles();
  1523.     }
  1524.     break;
  1525.   }
  1526.   case ltFUNC:
  1527.   case ltPFUNC:
  1528.   {
  1529.     SetCurrentOutput(winHelp ? Subsections : Chapters);
  1530.     if (start)
  1531.     {
  1532.       TexOutput("{");
  1533.     }
  1534.     else
  1535.     {
  1536.       TexOutput("}\n");
  1537.       if (winHelp)
  1538.       {
  1539.         fprintf(Subsections, "K{\\footnote ");
  1540.         suppressNameDecoration = TRUE;
  1541.         TraverseChildrenFromChunk(currentMember);
  1542.         suppressNameDecoration = FALSE;
  1543.         fprintf(Subsections, "}\n");
  1544.       }
  1545.       if (!winHelp)
  1546.       {
  1547.         // Insert index entry for this function
  1548.         TexOutput("{\\xe\\v {");
  1549.         suppressNameDecoration = TRUE;  // Necessary so don't print "(\\bf" etc.
  1550.         TraverseChildrenFromChunk(currentMember);
  1551.         suppressNameDecoration = FALSE;
  1552.         TexOutput("}}");
  1553.       }
  1554.     }
  1555.     break;
  1556.   }
  1557.   case ltCLIPSFUNC:
  1558.   {
  1559.     SetCurrentOutput(winHelp ? Subsections : Chapters);
  1560.     if (start)
  1561.     {
  1562.       TexOutput("{");
  1563.     }
  1564.     else
  1565.     {
  1566.       TexOutput("}\n");
  1567.       if (winHelp)
  1568.       {
  1569.         fprintf(Subsections, "K{\\footnote ");
  1570.         suppressNameDecoration = TRUE;  // Necessary so don't print "(\\bf" etc.
  1571.         TraverseChildrenFromChunk(currentMember);
  1572.         suppressNameDecoration = FALSE;
  1573.         fprintf(Subsections, "}\n");
  1574.       }
  1575.       if (!winHelp)
  1576.       {
  1577.         // Insert index entry for this function
  1578.         TexOutput("{\\xe\\v {");
  1579.         suppressNameDecoration = TRUE;  // Necessary so don't print "(\\bf" etc.
  1580.         TraverseChildrenFromChunk(currentMember);
  1581.         suppressNameDecoration = FALSE;
  1582.         TexOutput("}}");
  1583.       }
  1584.     }
  1585.     break;
  1586.   }
  1587.   case ltMEMBER:
  1588.   {
  1589.     SetCurrentOutput(winHelp ? Subsections : Chapters);
  1590.     if (start)
  1591.     {
  1592.       TexOutput("{\\b ");
  1593.     }
  1594.     else
  1595.     {
  1596.       TexOutput("}\n");
  1597.       if (winHelp)
  1598.       {
  1599.         fprintf(Subsections, "K{\\footnote ");
  1600.         TraverseChildrenFromChunk(currentMember);
  1601.         fprintf(Subsections, "}\n");
  1602.       }
  1603.       if (!winHelp)
  1604.       {
  1605.         // Insert index entry for this function
  1606.         TexOutput("{\\xe\\v {");
  1607.         suppressNameDecoration = TRUE;  // Necessary so don't print "(\\bf" etc.
  1608.         TraverseChildrenFromChunk(currentMember);
  1609.         suppressNameDecoration = FALSE;
  1610.         TexOutput("}}");
  1611.       }
  1612.     }
  1613.     break;
  1614.   }
  1615.   case ltDOCUMENT:
  1616.   {
  1617.     if (start)
  1618.       SetCurrentOutput(Chapters);
  1619.     break;
  1620.   }
  1621.   case ltTABLEOFCONTENTS:
  1622.   {
  1623.     if (start)
  1624.     {
  1625.       if (!winHelp && useWord)
  1626.       {
  1627.         // Insert Word for Windows table of contents
  1628.         TexOutput("\\par\\pard\\pgnrestart\\sect\\titlepg");
  1629.  
  1630.        // In linear RTF, same as chapter headings.
  1631.         sprintf(buf, "{\\b\\fs%d %s}\\par\\par\\pard\n\n", chapterFont*2, ContentsNameString);
  1632.  
  1633.         TexOutput(buf);
  1634.         TexOutput("{\\field{\\*\\fldinst TOC \\\\o \"1-4\" }{\\fldrslt PRESS F9 TO REFORMAT CONTENTS}}\n");
  1635. //        TexOutput("\\sect\\sectd");
  1636.       }
  1637.       else
  1638.       {
  1639.         FILE *fd = fopen(ContentsName, "r");
  1640.         if (fd)
  1641.         {
  1642.           char ch = getc(fd);
  1643.           while (ch != EOF)
  1644.           {
  1645.             putc(ch, Chapters);
  1646.             ch = getc(fd);
  1647.           }
  1648.           fclose(fd);
  1649.         }
  1650.         else
  1651.         {
  1652.           TexOutput("{\\i RUN TEX2RTF AGAIN FOR CONTENTS PAGE}\\par\n");
  1653.           OnInform("Run Tex2RTF again to include contents page.");
  1654.         }
  1655.       }
  1656.     }
  1657.     break;
  1658.   }
  1659.   case ltVOID:
  1660.   {
  1661.     if (start)
  1662.       TexOutput("{\\b void}");
  1663.     break;
  1664.   }
  1665.   case ltHARDY:
  1666.   {
  1667.     if (start)
  1668.       TexOutput("{\\scaps HARDY}");
  1669.     break;
  1670.   }
  1671.   case ltWXCLIPS:
  1672.   {
  1673.     if (start)
  1674.       TexOutput("wxCLIPS");
  1675.     break;
  1676.   }
  1677.   case ltSPECIALAMPERSAND:
  1678.   {
  1679. /*
  1680.     if (inTable)
  1681.       TexOutput("\\tab\n");
  1682.     else
  1683.       TexOutput("&");
  1684. */
  1685.     if (start)
  1686.     {
  1687.       if (inTabular)
  1688.         TexOutput("\\cell ");
  1689.       else
  1690.         TexOutput("&");
  1691.     }
  1692.     break;
  1693.   }
  1694.   case ltBACKSLASHCHAR:
  1695.   {
  1696.     if (start)
  1697.     {
  1698.       if (inTabular)
  1699.       {
  1700. //        TexOutput("\\cell\\row\\trowd\\trgaph108\\trleft-108\n");
  1701.         TexOutput("\\cell\\row\\trowd\\trgaph108\n");
  1702.         int currentWidth = 0;
  1703.         for (int i = 0; i < noColumns; i++)
  1704.         {
  1705.           currentWidth += TableData[i].width;
  1706.           if (TableData[i].rightBorder)
  1707.             TexOutput("\\clbrdrr\\brdrs\\brdrw15");
  1708.  
  1709.           if (TableData[i].leftBorder)
  1710.             TexOutput("\\clbrdrl\\brdrs\\brdrw15");
  1711.           
  1712.           sprintf(buf, "\\cellx%d", currentWidth);
  1713.           TexOutput(buf);
  1714.         }
  1715.         TexOutput("\\pard\\intbl\n");
  1716.       }
  1717.       else
  1718.         TexOutput("\\line\n");
  1719.     }
  1720.     break;
  1721. /*
  1722.     if (start)
  1723.     {
  1724.     if (inTabular)
  1725. //      TexOutput("\\cell\n\\row\\pard\n\\intbl\n");
  1726.     {
  1727.       if (tableVerticalLineLeft)
  1728.         TexOutput("\\brdrl\\brdrs");
  1729.       if (tableVerticalLineRight)
  1730.         TexOutput("\\brdrr\\brdrs");
  1731.  
  1732.       TexOutput("\\par\\pard\n");
  1733.  
  1734.       // Calculate a rough size for each column
  1735.       int colSize = 6000/(noColumns-1);
  1736.       int colPos = colSize;
  1737.       for (int j = 0; j < noColumns; j++)
  1738.       {
  1739.         sprintf(buf, "\\tx%d", colPos);
  1740.         TexOutput(buf);
  1741.         colPos += colSize;
  1742.       }
  1743.       TexOutput("\n");
  1744.     }
  1745.     else
  1746.       TexOutput("\\line\n");
  1747.     }
  1748. */
  1749.     break;
  1750.   }
  1751.   case ltRANGLEBRA:
  1752.   {
  1753.     if (start)
  1754.       TexOutput("\tab ");
  1755.     break;
  1756.   }
  1757.   case ltRTFSP:  // Explicit space, RTF only
  1758.   {
  1759.     if (start)
  1760.       TexOutput(" ");
  1761.    break;
  1762.   }
  1763.   case ltITEMIZE:
  1764.   case ltENUMERATE:
  1765.   case ltDESCRIPTION:
  1766.   {
  1767.     if (start)
  1768.     {
  1769.       if (indentLevel > 0)
  1770.       {
  1771.         TexOutput("\\par\\par\n");
  1772.       }
  1773.       else
  1774.       {
  1775.         // Top-level list: issue a new paragraph if we haven't
  1776.         // just done so
  1777.         if (!issuedNewParagraph)
  1778.         {
  1779.           TexOutput("\\par\\pard");
  1780.           WriteEnvironmentStyles();
  1781.           issuedNewParagraph = TRUE;
  1782.         }
  1783.         else issuedNewParagraph = FALSE;
  1784.       }
  1785.       indentLevel ++;
  1786.       TexOutput("\\fi0\n");
  1787.       int listType;
  1788.       if (macroId == ltENUMERATE)
  1789.         listType = LATEX_ENUMERATE;
  1790.       else if (macroId == ltITEMIZE)
  1791.         listType = LATEX_ITEMIZE;
  1792.       else
  1793.         listType = LATEX_DESCRIPTION;
  1794.  
  1795.       int oldIndent = 0;
  1796.       wxNode *node = itemizeStack.First();
  1797.       if (node)
  1798.         oldIndent = ((ItemizeStruc *)node->Data())->indentation;
  1799.  
  1800.       int indentSize1 = oldIndent + 20*labelIndentTab;
  1801.       int indentSize2 = oldIndent + 20*itemIndentTab;
  1802.  
  1803.       ItemizeStruc *struc = new ItemizeStruc(listType, indentSize2, indentSize1);
  1804.       itemizeStack.Insert(struc);
  1805.       
  1806.       sprintf(buf, "\\tx%d\\tx%d\\li%d", indentSize1, indentSize2, indentSize2);
  1807.       PushEnvironmentStyle(buf);
  1808.     }
  1809.     else
  1810.     {
  1811.       currentItemSep = 8; // Reset to the default
  1812.       indentLevel --;
  1813.       PopEnvironmentStyle();
  1814.  
  1815.       if (itemizeStack.First())
  1816.       {
  1817.         ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
  1818.         delete struc;
  1819.         delete itemizeStack.First();
  1820.       }
  1821.  
  1822.       if (itemizeStack.Number() == 0)
  1823.       {
  1824.         OnMacro(ltPAR, 0, TRUE);
  1825.         OnMacro(ltPAR, 0, FALSE);
  1826.       }
  1827.     }
  1828.     break;
  1829.   }
  1830.   case ltTWOCOLLIST:
  1831.   {
  1832.     if (start)
  1833.     {
  1834.       indentLevel ++;
  1835.       int oldIndent = 0;
  1836.       wxNode *node = itemizeStack.First();
  1837.       if (node)
  1838.         oldIndent = ((ItemizeStruc *)node->Data())->indentation;
  1839.  
  1840.       int indentSize = oldIndent + TwoColWidthA;
  1841.  
  1842.       ItemizeStruc *struc = new ItemizeStruc(LATEX_TWOCOL, indentSize);
  1843.       itemizeStack.Insert(struc);
  1844.       
  1845. //      sprintf(buf, "\\tx%d\\li%d\\ri%d", indentSize, indentSize, TwoColWidthA+TwoColWidthB+oldIndent);
  1846.       sprintf(buf, "\\tx%d\\li%d", indentSize, indentSize);
  1847.       PushEnvironmentStyle(buf);
  1848.     }
  1849.     else
  1850.     {
  1851.       indentLevel --;
  1852.       PopEnvironmentStyle();
  1853.       if (itemizeStack.First())
  1854.       {
  1855.         ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
  1856.         delete struc;
  1857.         delete itemizeStack.First();
  1858.       }
  1859.       if (itemizeStack.Number() == 0)
  1860.       {
  1861.         OnMacro(ltPAR, 0, TRUE);
  1862.         OnMacro(ltPAR, 0, FALSE);
  1863.       }
  1864.     }
  1865.     break;
  1866.   }
  1867.   case ltITEM:
  1868.   {
  1869.     wxNode *node = itemizeStack.First();
  1870.     if (node)
  1871.     {
  1872.       ItemizeStruc *struc = (ItemizeStruc *)node->Data();
  1873.       if (!start)
  1874.       {
  1875.         struc->currentItem += 1;
  1876.         char indentBuf[60];
  1877.  
  1878.         int indentSize1 = struc->labelIndentation;
  1879.         int indentSize2 = struc->indentation;
  1880.  
  1881.         TexOutput("\n");
  1882.         if (struc->currentItem > 1)
  1883.         {
  1884.           if (currentItemSep > 0)
  1885.             TexOutput("\\par");
  1886.  
  1887.           TexOutput("\\par");
  1888. //          WriteEnvironmentStyles();
  1889.         }
  1890.  
  1891.         sprintf(buf, "\\tx%d\\tx%d\\li%d\\fi-%d\n", indentSize1, indentSize2,
  1892.                   indentSize2, 20*itemIndentTab);
  1893.         TexOutput(buf);
  1894.  
  1895.         switch (struc->listType)
  1896.         {
  1897.           case LATEX_ENUMERATE:
  1898.           {
  1899.             if (descriptionItemArg)
  1900.             {
  1901.               TexOutput("\\tab{ ");
  1902.               TraverseChildrenFromChunk(descriptionItemArg);
  1903.               TexOutput("}\\tab");
  1904.               descriptionItemArg = NULL;
  1905.         }
  1906.         else
  1907.         {
  1908.               sprintf(indentBuf, "\\tab{\\b %d.}\\tab", struc->currentItem);
  1909.               TexOutput(indentBuf);
  1910.             }
  1911.             break;
  1912.           }
  1913.           case LATEX_ITEMIZE:
  1914.           {
  1915.             if (descriptionItemArg)
  1916.             {
  1917.               TexOutput("\\tab{ ");
  1918.               TraverseChildrenFromChunk(descriptionItemArg);
  1919.               TexOutput("}\\tab");
  1920.               descriptionItemArg = NULL;
  1921.         }
  1922.         else
  1923.         {
  1924.               if (bulletFile && winHelp)
  1925.                 sprintf(indentBuf, "\\tab\\{bmc %s\\}\\tab", bulletFile);
  1926.               else if (winHelp)
  1927.                 sprintf(indentBuf, "\\tab{\\b o}\\tab");
  1928.               else
  1929.                 sprintf(indentBuf, "\\tab{\\f1\\'b7}\\tab");
  1930.               TexOutput(indentBuf);
  1931.             }
  1932.             break;
  1933.           }
  1934.           default:
  1935.           case LATEX_DESCRIPTION:
  1936.           {
  1937.             if (descriptionItemArg)
  1938.             {
  1939.               TexOutput("\\tab{\\b ");
  1940.               TraverseChildrenFromChunk(descriptionItemArg);
  1941.               TexOutput("}  ");
  1942.               descriptionItemArg = NULL;
  1943.             }
  1944.             break;
  1945.           }
  1946.     }
  1947.       }
  1948.     }
  1949.     break;
  1950.   }
  1951.   case ltTWOCOLITEM:
  1952.   case ltTWOCOLITEMRULED:
  1953.   {
  1954.     wxNode *node = itemizeStack.First();
  1955.     if (node)
  1956.     {
  1957.       ItemizeStruc *struc = (ItemizeStruc *)node->Data();
  1958.       if (start)
  1959.       {
  1960.         struc->currentItem += 1;
  1961.  
  1962.         int indentSize = struc->indentation;
  1963.         int oldIndent = 0;
  1964.         wxNode *node2 = itemizeStack.Nth(1);
  1965.         if (node2)
  1966.           oldIndent = ((ItemizeStruc *)node2->Data())->indentation;
  1967.  
  1968.         TexOutput("\n");
  1969.         if (struc->currentItem > 1)
  1970.         {
  1971.           if (currentItemSep > 0)
  1972.             TexOutput("\\par");
  1973.  
  1974. //          WriteEnvironmentStyles();
  1975.         }
  1976.  
  1977. //        sprintf(buf, "\\tx%d\\li%d\\fi-%d\\ri%d\n", TwoColWidthA,
  1978. //             TwoColWidthA, TwoColWidthA, TwoColWidthA+TwoColWidthB+oldIndent);
  1979.         sprintf(buf, "\\tx%d\\li%d\\fi-%d\n", TwoColWidthA,
  1980.              TwoColWidthA, TwoColWidthA);
  1981.         TexOutput(buf);
  1982.       }
  1983.     }
  1984.     break;
  1985.   }
  1986.   case ltVERBATIM:
  1987.   case ltVERB:
  1988.   {
  1989.     if (start)
  1990.     {
  1991.       if (macroId == ltVERBATIM)
  1992.       {
  1993.         if (!issuedNewParagraph)
  1994.         {
  1995.           TexOutput("\\par\\pard");
  1996.           WriteEnvironmentStyles();
  1997.           issuedNewParagraph = TRUE;
  1998.         }
  1999.         else issuedNewParagraph = FALSE;
  2000.       }
  2001.       sprintf(buf, "{\\f3\\fs20 ");
  2002.       TexOutput(buf);
  2003.     }
  2004.     else
  2005.     {
  2006.       TexOutput("}");
  2007.       if (macroId == ltVERBATIM)
  2008.       {
  2009.         TexOutput("\\pard\n");
  2010. //        issuedNewParagraph = TRUE;
  2011.         WriteEnvironmentStyles();
  2012.       }
  2013.     }
  2014.     break;
  2015.   }
  2016.   case ltCENTERLINE:
  2017.   case ltCENTER:
  2018.   {
  2019.     if (start)
  2020.     {
  2021.       TexOutput("\\fi0\\qc ");
  2022.       forbidParindent ++;
  2023.       PushEnvironmentStyle("\\qc");
  2024.     }
  2025.     else
  2026.     {
  2027.       TexOutput("\\par\\pard\n");
  2028.       issuedNewParagraph = TRUE;
  2029.       forbidParindent --;
  2030.       PopEnvironmentStyle();
  2031.       WriteEnvironmentStyles();
  2032.     }
  2033.     break;
  2034.   }
  2035.   case ltFLUSHLEFT:
  2036.   {
  2037.     if (start)
  2038.     {
  2039.       TexOutput("\\fi0\\ql ");
  2040.       forbidParindent ++;
  2041.       PushEnvironmentStyle("\\ql");
  2042.     }
  2043.     else
  2044.     {
  2045.       TexOutput("\\par\\pard\n");
  2046.       issuedNewParagraph = TRUE;
  2047.       forbidParindent --;
  2048.       PopEnvironmentStyle();
  2049.       WriteEnvironmentStyles();
  2050.     }
  2051.     break;
  2052.   }
  2053.   case ltFLUSHRIGHT:
  2054.   {
  2055.     if (start)
  2056.     {
  2057.       TexOutput("\\fi0\\qr ");
  2058.       forbidParindent ++;
  2059.       PushEnvironmentStyle("\\qr");
  2060.     }
  2061.     else
  2062.     {
  2063.       TexOutput("\\par\\pard\n");
  2064.       issuedNewParagraph = TRUE;
  2065.       forbidParindent --;
  2066.       PopEnvironmentStyle();
  2067.       WriteEnvironmentStyles();
  2068.     }
  2069.     break;
  2070.   }
  2071.   case ltSMALL:
  2072.   case ltFOOTNOTESIZE:
  2073.   {
  2074.     if (start)
  2075.     {
  2076.       sprintf(buf, "{\\fs%d\n", smallFont*2);
  2077.       TexOutput(buf);
  2078.     }
  2079.     else TexOutput("}\n");
  2080.     break;
  2081.   }
  2082.   case ltTINY:
  2083.   case ltSCRIPTSIZE:
  2084.   {
  2085.     if (start)
  2086.     {
  2087.       sprintf(buf, "{\\fs%d\n", tinyFont*2);
  2088.       TexOutput(buf);
  2089.     }
  2090.     else TexOutput("}\n");
  2091.     break;
  2092.   }
  2093.   case ltNORMALSIZE:
  2094.   {
  2095.     if (start)
  2096.     {
  2097.       sprintf(buf, "{\\fs%d\n", normalFont*2);
  2098.       TexOutput(buf);
  2099.     }
  2100.     else TexOutput("}\n");
  2101.     break;
  2102.   }
  2103.   case ltlarge:
  2104.   {
  2105.     if (start)
  2106.     {
  2107.       sprintf(buf, "{\\fs%d\n", largeFont1*2);
  2108.       TexOutput(buf);
  2109.     }
  2110.     else TexOutput("}\n");
  2111.     break;
  2112.   }
  2113.   case ltLarge:
  2114.   {
  2115.     if (start)
  2116.     {
  2117.       sprintf(buf, "{\\fs%d\n", LargeFont2*2);
  2118.       TexOutput(buf);
  2119.     }
  2120.     else TexOutput("}\n");
  2121.     break;
  2122.   }
  2123.   case ltLARGE:
  2124.   {
  2125.     if (start)
  2126.     {
  2127.       sprintf(buf, "{\\fs%d\n", LARGEFont3*2);
  2128.       TexOutput(buf);
  2129.     }
  2130.     else TexOutput("}\n");
  2131.     break;
  2132.   }
  2133.   case lthuge:
  2134.   {
  2135.     if (start)
  2136.     {
  2137.       sprintf(buf, "{\\fs%d\n", hugeFont1*2);
  2138.       TexOutput(buf);
  2139.     }
  2140.     else TexOutput("}\n");
  2141.     break;
  2142.   }
  2143.   case ltHuge:
  2144.   {
  2145.     if (start)
  2146.     {
  2147.       sprintf(buf, "{\\fs%d\n", HugeFont2*2);
  2148.       TexOutput(buf);
  2149.     }
  2150.     else TexOutput("}\n");
  2151.     break;
  2152.   }
  2153.   case ltHUGE:
  2154.   {
  2155.     if (start)
  2156.     {
  2157.       sprintf(buf, "{\\fs%d\n", HUGEFont3*2);
  2158.       TexOutput(buf);
  2159.     }
  2160.     else TexOutput("}\n");
  2161.     break;
  2162.   }
  2163.   case ltBF:
  2164.   {
  2165.     if (start)
  2166.     {
  2167.       TexOutput("{\\b ");
  2168.     }
  2169.     else TexOutput("}");
  2170.     break;
  2171.   }
  2172.   case ltUNDERLINE:
  2173.   {
  2174.     if (start)
  2175.     {
  2176.       TexOutput("{\\ul ");
  2177.     }
  2178.     else TexOutput("}");
  2179.     break;
  2180.   }
  2181.   case ltIT:
  2182.   case ltEM:
  2183.   {
  2184.     if (start)
  2185.     {
  2186.       TexOutput("{\\i ");
  2187.     }
  2188.     else TexOutput("}");
  2189.     break;
  2190.   }
  2191.   case ltRM:
  2192.   {
  2193. /*    
  2194.     if (start)
  2195.     {
  2196.       TexOutput("{\\plain ");
  2197.     }
  2198.     else TexOutput("}");
  2199.  */
  2200.     break;
  2201.   }
  2202.   case ltSC:
  2203.   {
  2204.     if (start)
  2205.     {
  2206.       TexOutput("{\\scaps ");
  2207.     }
  2208.     else TexOutput("}");
  2209.     break;
  2210.   }
  2211.   case ltTT:
  2212.   {
  2213.     if (start)
  2214.     {
  2215.       TexOutput("{\\f3 ");
  2216.     }
  2217.     else TexOutput("}");
  2218.     break;
  2219.   }
  2220.   case ltLBRACE:
  2221.   {
  2222.     if (start)
  2223.       TexOutput("\\{");
  2224.     break;
  2225.   }
  2226.   case ltRBRACE:
  2227.   {
  2228.     if (start)
  2229.       TexOutput("\\}");
  2230.     break;
  2231.   }
  2232.   case ltBACKSLASH:
  2233.   {
  2234.     if (start)
  2235.       TexOutput("\\\\");
  2236.     break;
  2237.   }
  2238.   case ltPAR:
  2239.   {
  2240.     if (start)
  2241.     {
  2242.       if (!issuedNewParagraph || (issuedNewParagraph > 1))
  2243.       {
  2244.         TexOutput("\\par\\pard");
  2245.  
  2246.         // Extra par if parskip is more than zero (usually looks best.)
  2247.         if (!inTabular && (ParSkip > 0))
  2248.           TexOutput("\\par");
  2249.         WriteEnvironmentStyles();
  2250.       }
  2251.       issuedNewParagraph ++;
  2252.       TexOutput("\n");
  2253.     }
  2254.     break;
  2255.   }
  2256.   case ltNEWPAGE:
  2257.   {
  2258.     // In Windows Help, no newpages until we've started some chapters or sections
  2259.     if (!(winHelp && !startedSections))
  2260.       if (start)
  2261.         TexOutput("\\page\n");
  2262.     break;
  2263.   }
  2264.   case ltMAKETITLE:
  2265.   {
  2266.     if (start && DocumentTitle)
  2267.     {
  2268.       TexOutput("\\par\\pard");
  2269.       if (!winHelp)
  2270.         TexOutput("\\par");
  2271.       sprintf(buf, "\\qc{\\fs%d\\b ", titleFont*2);
  2272.       TexOutput(buf);
  2273.       TraverseChildrenFromChunk(DocumentTitle);
  2274.       TexOutput("}\\par\\pard\n");
  2275.  
  2276.       if (DocumentAuthor)
  2277.       {
  2278.         if (!winHelp)
  2279.           TexOutput("\\par");
  2280.         sprintf(buf, "\\par\\qc{\\fs%d ", authorFont*2);
  2281.         TexOutput(buf);
  2282.         TraverseChildrenFromChunk(DocumentAuthor);
  2283.         TexOutput("}");
  2284.         TexOutput("\\par\\pard\n");
  2285.       }
  2286.       if (DocumentDate)
  2287.       {
  2288.         TexOutput("\\par");
  2289.         sprintf(buf, "\\qc{\\fs%d ", authorFont*2);
  2290.         TexOutput(buf);
  2291.         TraverseChildrenFromChunk(DocumentDate);
  2292.         TexOutput("}\\par\\pard\n");
  2293.       }
  2294.       // If linear RTF, we want this titlepage to be in a separate
  2295.       // section with its own (blank) header and footer
  2296.       if (!winHelp && (DocumentStyle != LATEX_ARTICLE))
  2297.       {
  2298.         TexOutput("{\\header }{\\footer }\n");
  2299.         // Not sure about this: we get too many sections.
  2300. //        TexOutput("\\sect");
  2301.       }
  2302.     }
  2303.     break;
  2304.   }
  2305.   case ltADDCONTENTSLINE:
  2306.   {
  2307.     if (!start)
  2308.     {
  2309.     if (contentsLineSection && contentsLineValue)
  2310.     {
  2311.       if (strcmp(contentsLineSection, "chapter") == 0)
  2312.       {
  2313.         fprintf(Contents, "\\par\n{\\b %s}\\par\n", contentsLineValue);
  2314.       }
  2315.       else if (strcmp(contentsLineSection, "section") == 0)
  2316.       {
  2317.         if (DocumentStyle != LATEX_ARTICLE)
  2318.           fprintf(Contents, "\n\\tab%s\\par\n", contentsLineValue);
  2319.         else
  2320.           fprintf(Contents, "\\par\n{\\b %s}\\par\n", contentsLineValue);
  2321.       }
  2322.     }
  2323.     }
  2324.     break;
  2325.   }
  2326.   case ltHRULE:
  2327.   {
  2328.     if (start)
  2329.     {
  2330.       TexOutput("\\brdrb\\brdrs\\par\\pard\n");
  2331.       issuedNewParagraph = TRUE;
  2332.       WriteEnvironmentStyles();
  2333.     }
  2334.     break;
  2335.   }
  2336.   case ltRULE:
  2337.   {
  2338.     if (start)
  2339.     {
  2340.       TexOutput("\\brdrb\\brdrs\\par\\pard\n");
  2341.       issuedNewParagraph = TRUE;
  2342.       WriteEnvironmentStyles();
  2343.     }
  2344.     break;
  2345.   }
  2346.   case ltHLINE:
  2347.   {
  2348.     if (start)
  2349.       ruleTop ++;
  2350.     break;
  2351.   }
  2352.   case ltNUMBEREDBIBITEM:
  2353.   {
  2354.     if (start)
  2355.       TexOutput("\\li260\\fi-260 "); // Indent from 2nd line
  2356.     else
  2357.       TexOutput("\\par\\pard\\par\n\n");
  2358.     break;
  2359.   }
  2360.   case ltTHEPAGE:
  2361.   {
  2362.     if (start)
  2363.     {
  2364.       TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  2365.     }
  2366.     break;
  2367.   }
  2368.   case ltTHECHAPTER:
  2369.   {
  2370.     if (start)
  2371.     {
  2372. //      TexOutput("{\\field{\\*\\fldinst SECTION \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  2373.       sprintf(buf, "%d", chapterNo);
  2374.       TexOutput(buf);
  2375.     }
  2376.     break;
  2377.   }
  2378.   case ltTHESECTION:
  2379.   {
  2380.     if (start)
  2381.     {
  2382. //      TexOutput("{\\field{\\*\\fldinst SECTION \\\\* MERGEFORMAT }{\\fldrslt 1}}");
  2383.       sprintf(buf, "%d", sectionNo);
  2384.       TexOutput(buf);
  2385.     }
  2386.     break;
  2387.   }
  2388.   case ltTWOCOLUMN:
  2389.   {
  2390.     if (!start && !winHelp)
  2391.     {
  2392.       TexOutput("\\cols2\n");
  2393.     }
  2394.     break;
  2395.   }
  2396.   case ltONECOLUMN:
  2397.   {
  2398.     if (!start && !winHelp)
  2399.     {
  2400.       TexOutput("\\cols1\n");
  2401.     }
  2402.     break;
  2403.   }
  2404.   case ltPRINTINDEX:
  2405.   {
  2406.     if (start && !winHelp)
  2407.     {
  2408.       FakeCurrentSection("Index");
  2409.       OnMacro(ltPAR, 0, TRUE);
  2410.       OnMacro(ltPAR, 0, FALSE);
  2411.       TexOutput("\\par{\\field{\\*\\fldinst INDEX \\\\h \"\\emdash A\\emdash \"\\\\c \"2\"}{\\fldrslt PRESS F9 TO REFORMAT INDEX}}\n");
  2412.     }
  2413.     break;
  2414.   }
  2415.   case ltLISTOFFIGURES:
  2416.   {
  2417.     if (start && !winHelp)
  2418.     {
  2419.       FakeCurrentSection(FiguresNameString, FALSE);
  2420.       OnMacro(ltPAR, 0, TRUE);
  2421.       OnMacro(ltPAR, 0, FALSE);
  2422.       OnMacro(ltPAR, 0, TRUE);
  2423.       OnMacro(ltPAR, 0, FALSE);
  2424.       char buf[200];
  2425.       sprintf(buf, "{\\field\\fldedit{\\*\\fldinst  TOC \\\\c \"%s\" }{\\fldrslt PRESS F9 TO REFORMAT LIST OF FIGURES}}\n",
  2426.                FigureNameString);
  2427.       TexOutput(buf);
  2428.     }
  2429.     break;
  2430.   }
  2431.   case ltLISTOFTABLES:
  2432.   {
  2433.     if (start && !winHelp)
  2434.     {
  2435.       FakeCurrentSection(TablesNameString, FALSE);
  2436.       OnMacro(ltPAR, 0, TRUE);
  2437.       OnMacro(ltPAR, 0, FALSE);
  2438.       OnMacro(ltPAR, 0, TRUE);
  2439.       OnMacro(ltPAR, 0, FALSE);
  2440.       char buf[200];
  2441.       sprintf(buf, "{\\field\\fldedit{\\*\\fldinst  TOC \\\\c \"%s\" }{\\fldrslt PRESS F9 TO REFORMAT LIST OF TABLES}}\n",
  2442.                 TablesNameString);
  2443.       TexOutput(buf);
  2444.     }
  2445.     break;
  2446.   }
  2447.   // Symbols
  2448.   case ltALPHA:
  2449.     if (start) TexOutput("{\\f1\\'61}");
  2450.     break;
  2451.   case ltBETA:
  2452.     if (start) TexOutput("{\\f1\\'62}");
  2453.     break;
  2454.   case ltGAMMA:
  2455.     if (start) TexOutput("{\\f1\\'63}");
  2456.     break;
  2457.   case ltDELTA:
  2458.     if (start) TexOutput("{\\f1\\'64}");
  2459.     break;
  2460.   case ltEPSILON:
  2461.   case ltVAREPSILON:
  2462.     if (start) TexOutput("{\\f1\\'65}");
  2463.     break;
  2464.   case ltZETA:
  2465.     if (start) TexOutput("{\\f1\\'7A}");
  2466.     break;
  2467.   case ltETA:
  2468.     if (start) TexOutput("{\\f1\\'68}");
  2469.     break;
  2470.   case ltTHETA:
  2471.   case ltVARTHETA:
  2472.     if (start) TexOutput("{\\f1\\'71}");
  2473.     break;
  2474.   case ltIOTA:
  2475.     if (start) TexOutput("{\\f1\\'69}");
  2476.     break;
  2477.   case ltKAPPA:
  2478.     if (start) TexOutput("{\\f1\\'6B}");
  2479.     break;
  2480.   case ltLAMBDA:
  2481.     if (start) TexOutput("{\\f1\\'6C}");
  2482.     break;
  2483.   case ltMU:
  2484.     if (start) TexOutput("{\\f1\\'6D}");
  2485.     break;
  2486.   case ltNU:
  2487.     if (start) TexOutput("{\\f1\\'6E}");
  2488.     break;
  2489.   case ltXI:
  2490.     if (start) TexOutput("{\\f1\\'78}");
  2491.     break;
  2492.   case ltPI:
  2493.     if (start) TexOutput("{\\f1\\'70}");
  2494.     break;
  2495.   case ltVARPI:
  2496.     if (start) TexOutput("{\\f1\\'76}");
  2497.     break;
  2498.   case ltRHO:
  2499.   case ltVARRHO:
  2500.     if (start) TexOutput("{\\f1\\'72}");
  2501.     break;
  2502.   case ltSIGMA:
  2503.     if (start) TexOutput("{\\f1\\'73}");
  2504.     break;
  2505.   case ltVARSIGMA:
  2506.     if (start) TexOutput("{\\f1\\'56}");
  2507.     break;
  2508.   case ltTAU:
  2509.     if (start) TexOutput("{\\f1\\'74}");
  2510.     break;
  2511.   case ltUPSILON:
  2512.     if (start) TexOutput("{\\f1\\'75}");
  2513.     break;
  2514.   case ltPHI:
  2515.   case ltVARPHI:
  2516.     if (start) TexOutput("{\\f1\\'66}");
  2517.     break;
  2518.   case ltCHI:
  2519.     if (start) TexOutput("{\\f1\\'63}");
  2520.     break;
  2521.   case ltPSI:
  2522.     if (start) TexOutput("{\\f1\\'79}");
  2523.     break;
  2524.   case ltOMEGA:
  2525.     if (start) TexOutput("{\\f1\\'77}");
  2526.     break;
  2527.   case ltCAP_GAMMA:
  2528.     if (start) TexOutput("{\\f1\\'47}");
  2529.     break;
  2530.   case ltCAP_DELTA:
  2531.     if (start) TexOutput("{\\f1\\'44}");
  2532.     break;
  2533.   case ltCAP_THETA:
  2534.     if (start) TexOutput("{\\f1\\'51}");
  2535.     break;
  2536.   case ltCAP_LAMBDA:
  2537.     if (start) TexOutput("{\\f1\\'4C}");
  2538.     break;
  2539.   case ltCAP_XI:
  2540.     if (start) TexOutput("{\\f1\\'58}");
  2541.     break;
  2542.   case ltCAP_PI:
  2543.     if (start) TexOutput("{\\f1\\'50}");
  2544.     break;
  2545.   case ltCAP_SIGMA:
  2546.     if (start) TexOutput("{\\f1\\'53}");
  2547.     break;
  2548.   case ltCAP_UPSILON:
  2549.     if (start) TexOutput("{\\f1\\'54}");
  2550.     break;
  2551.   case ltCAP_PHI:
  2552.     if (start) TexOutput("{\\f1\\'46}");
  2553.     break;
  2554.   case ltCAP_PSI:
  2555.     if (start) TexOutput("{\\f1\\'59}");
  2556.     break;
  2557.   case ltCAP_OMEGA:
  2558.     if (start) TexOutput("{\\f1\\'57}");
  2559.     break;
  2560.   // Binary operation symbols
  2561.   case ltLE:
  2562.   case ltLEQ:
  2563.     if (start) TexOutput("{\\f1\\'A3}");
  2564.     break;
  2565.   case ltLL:
  2566.     if (start) TexOutput("<<");
  2567.     break;
  2568.   case ltSUBSET:
  2569.     if (start) TexOutput("{\\f1\\'CC}");
  2570.     break;
  2571.   case ltSUBSETEQ:
  2572.     if (start) TexOutput("{\\f1\\'CD}");
  2573.     break;
  2574.   case ltIN:
  2575.     if (start) TexOutput("{\\f1\\'CE}");
  2576.     break;
  2577.   case ltGE:
  2578.   case ltGEQ:
  2579.     if (start) TexOutput("{\\f1\\'B3}");
  2580.     break;
  2581.   case ltGG:
  2582.     if (start) TexOutput(">>");
  2583.     break;
  2584.   case ltSUPSET:
  2585.     if (start) TexOutput("{\\f1\\'C9}");
  2586.     break;
  2587.   case ltSUPSETEQ:
  2588.     if (start) TexOutput("{\\f1\\'CD}");
  2589.     break;
  2590.   case ltNI:
  2591.     if (start) TexOutput("{\\f1\\'27}");
  2592.     break;
  2593.   case ltPERP:
  2594.     if (start) TexOutput("{\\f1\\'5E}");
  2595.     break;
  2596.   case ltNEQ:
  2597.     if (start) TexOutput("{\\f1\\'B9}");
  2598.     break;
  2599.   case ltAPPROX:
  2600.     if (start) TexOutput("{\\f1\\'BB}");
  2601.     break;
  2602.   case ltCONG:
  2603.     if (start) TexOutput("{\\f1\\'40}");
  2604.     break;
  2605.   case ltEQUIV:
  2606.     if (start) TexOutput("{\\f1\\'BA}");
  2607.     break;
  2608.   case ltPROPTO:
  2609.     if (start) TexOutput("{\\f1\\'B5}");
  2610.     break;
  2611.   case ltSIM:
  2612.     if (start) TexOutput("{\\f1\\'7E}");
  2613.     break;
  2614.   case ltSMILE:
  2615.     if (start) TexOutput("{\\f4\\'4A}");
  2616.     break;
  2617.   case ltFROWN:
  2618.     if (start) TexOutput("{\\f4\\'4C}");
  2619.     break;
  2620.   case ltMID:
  2621.     if (start) TexOutput("|");
  2622.     break;
  2623.  
  2624.   // Negated relation symbols
  2625.   case ltNOTEQ:
  2626.     if (start) TexOutput("{\\f1\\'B9}");
  2627.     break;
  2628.   case ltNOTIN:
  2629.     if (start) TexOutput("{\\f1\\'CF}");
  2630.     break;
  2631.   case ltNOTSUBSET:
  2632.     if (start) TexOutput("{\\f1\\'CB}");
  2633.     break;
  2634.  
  2635.   // Arrows
  2636.   case ltLEFTARROW:
  2637.      if (start) TexOutput("{\\f1\\'AC}");
  2638.     break;
  2639.   case ltLEFTARROW2:
  2640.     if (start) TexOutput("{\\f1\\'DC}");
  2641.     break;
  2642.   case ltRIGHTARROW:
  2643.     if (start) TexOutput("{\\f1\\'AE}");
  2644.     break;
  2645.   case ltRIGHTARROW2:
  2646.     if (start) TexOutput("{\\f1\\'DE}");
  2647.     break;
  2648.   case ltLEFTRIGHTARROW:
  2649.     if (start) TexOutput("{\\f1\\'AB}");
  2650.     break;
  2651.   case ltLEFTRIGHTARROW2:
  2652.     if (start) TexOutput("{\\f1\\'DB}");
  2653.     break;
  2654.   case ltUPARROW:
  2655.     if (start) TexOutput("{\\f1\\'AD}");
  2656.     break;
  2657.   case ltUPARROW2:
  2658.     if (start) TexOutput("{\\f1\\'DD}");
  2659.     break;
  2660.   case ltDOWNARROW:
  2661.     if (start) TexOutput("{\\f1\\'AF}");
  2662.     break;
  2663.   case ltDOWNARROW2:
  2664.     if (start) TexOutput("{\\f1\\'DF}");
  2665.     break;
  2666.  
  2667.   // Miscellaneous symbols
  2668.   case ltALEPH:
  2669.     if (start) TexOutput("{\\f1\\'CO}");
  2670.     break;
  2671.   case ltWP:
  2672.     if (start) TexOutput("{\\f1\\'C3}");
  2673.     break;
  2674.   case ltRE:
  2675.     if (start) TexOutput("{\\f1\\'C2}");
  2676.     break;
  2677.   case ltIM:
  2678.     if (start) TexOutput("{\\f1\\'C1}");
  2679.     break;
  2680.   case ltEMPTYSET:
  2681.     if (start) TexOutput("{\\f1\\'C6}");
  2682.     break;
  2683.   case ltNABLA:
  2684.     if (start) TexOutput("{\\f1\\'D1}");
  2685.     break;
  2686.   case ltSURD:
  2687.     if (start) TexOutput("{\\f1\\'D6}");
  2688.     break;
  2689.   case ltPARTIAL:
  2690.     if (start) TexOutput("{\\f1\\'B6}");
  2691.     break;
  2692.   case ltBOT:
  2693.     if (start) TexOutput("{\\f1\\'5E}");
  2694.     break;
  2695.   case ltFORALL:
  2696.     if (start) TexOutput("{\\f1\\'22}");
  2697.     break;
  2698.   case ltEXISTS:
  2699.     if (start) TexOutput("{\\f1\\'24}");
  2700.     break;
  2701.   case ltNEG:
  2702.     if (start) TexOutput("{\\f1\\'D8}");
  2703.     break;
  2704.   case ltSHARP:
  2705.     if (start) TexOutput("{\\f1\\'23}");
  2706.     break;
  2707.   case ltANGLE:
  2708.     if (start) TexOutput("{\\f1\\'D0}");
  2709.     break;
  2710.   case ltTRIANGLE:
  2711.     if (start) TexOutput("{\\f5\\'73}");
  2712.     break;
  2713.   case ltCLUBSUIT:
  2714.     if (start) TexOutput("{\\f5\\'A8}");
  2715.     break;
  2716.   case ltDIAMONDSUIT:
  2717.     if (start) TexOutput("{\\f5\\'A9}");
  2718.     break;
  2719.   case ltHEARTSUIT:
  2720.     if (start) TexOutput("{\\f5\\'AA}");
  2721.     break;
  2722.   case ltSPADESUIT:
  2723.     if (start) TexOutput("{\\f5\\'AB}");
  2724.     break;
  2725.   case ltINFTY:
  2726.     if (start) TexOutput("{\\f1\\'A5}");
  2727.     break;
  2728.   case ltCOPYRIGHT:
  2729.     if (start) TexOutput("{\\f1\\'E1}");
  2730.     break;
  2731.   case ltPM:
  2732.     if (start) TexOutput("{\\f1\\'B1}");
  2733.     break;
  2734.   case ltMP:
  2735.     if (start) TexOutput("{\\f1\\'B1}");
  2736.     break;
  2737.   case ltTIMES:
  2738.     if (start) TexOutput("{\\f1\\'B4}");
  2739.     break;
  2740.   case ltDIV:
  2741.     if (start) TexOutput("{\\f1\\'B8}");
  2742.     break;
  2743.   case ltCDOT:
  2744.     if (start) TexOutput("{\\f1\\'D7}");
  2745.     break;
  2746.   case ltAST:
  2747.     if (start) TexOutput("{\\f1\\'2A}");
  2748.     break;
  2749.   case ltSTAR:
  2750.     if (start) TexOutput("{\\f5\\'AB}");
  2751.     break;
  2752.   case ltCAP:
  2753.     if (start) TexOutput("{\\f1\\'C7}");
  2754.     break;
  2755.   case ltCUP:
  2756.     if (start) TexOutput("{\\f1\\'C8}");
  2757.     break;
  2758.   case ltVEE:
  2759.     if (start) TexOutput("{\\f1\\'DA}");
  2760.     break;
  2761.   case ltWEDGE:
  2762.     if (start) TexOutput("{\\f1\\'D9}");
  2763.     break;
  2764.   case ltCIRC:
  2765.     if (start) TexOutput("{\\f1\\'B0}");
  2766.     break;
  2767.   case ltBULLET:
  2768.     if (start) TexOutput("{\\f1\\'B7}");
  2769.     break;
  2770.   case ltDIAMOND:
  2771.     if (start) TexOutput("{\\f1\\'E0}");
  2772.     break;
  2773.   case ltBOX:
  2774.     if (start) TexOutput("{\\f1\\'C6}");
  2775.     break;
  2776.   case ltDIAMOND2:
  2777.     if (start) TexOutput("{\\f1\\'E0}");
  2778.     break;
  2779.   case ltBIGTRIANGLEDOWN:
  2780.     if (start) TexOutput("{\\f1\\'D1}");
  2781.     break;
  2782.   case ltOPLUS:
  2783.     if (start) TexOutput("{\\f1\\'C5}");
  2784.     break;
  2785.   case ltOTIMES:
  2786.     if (start) TexOutput("{\\f1\\'C4}");
  2787.     break;
  2788.   case ltSS:
  2789.     if (start) TexOutput("{\\'DF}");
  2790.     break;
  2791.   case ltFIGURE:
  2792.   {
  2793.     if (start) inFigure = TRUE;
  2794.     else inFigure = FALSE;
  2795.     break;
  2796.   }
  2797.   case ltTABLE:
  2798.   {
  2799.     if (start) inTable = TRUE;
  2800.     else inTable = FALSE;
  2801.     break;
  2802.   }
  2803.   default:
  2804.   {
  2805.     DefaultOnMacro(macroId, no_args, start);
  2806.     break;
  2807.   }
  2808.   }
  2809. }
  2810.  
  2811. // Called on start/end of argument examination
  2812. Bool RTFOnArgument(int macroId, int arg_no, Bool start)
  2813. {
  2814.   char buf[300];
  2815.   switch (macroId)
  2816.   {
  2817.   case ltCHAPTER:
  2818.   case ltCHAPTERSTAR:
  2819.   case ltCHAPTERHEADING:
  2820.   case ltSECTION:
  2821.   case ltSECTIONSTAR:
  2822.   case ltSECTIONHEADING:
  2823.   case ltSUBSECTION:
  2824.   case ltSUBSECTIONSTAR:
  2825.   case ltSUBSUBSECTION:
  2826.   case ltSUBSUBSECTIONSTAR:
  2827.   case ltGLOSS:
  2828.   case ltMEMBERSECTION:
  2829.   case ltFUNCTIONSECTION:
  2830.   case ltCAPTION:
  2831.   case ltCAPTIONSTAR:
  2832.   {
  2833.     if (!start && (arg_no == 1))
  2834.       currentSection = GetArgChunk();
  2835.     return FALSE;
  2836.     break;
  2837.   }
  2838.   case ltFUNC:
  2839.   {
  2840.     if (start && (arg_no == 1))
  2841.       TexOutput("\\pard\\li260\\fi-260{\\b ");
  2842.  
  2843.     if (!start && (arg_no == 1))
  2844.       TexOutput("} ");
  2845.  
  2846.     if (start && (arg_no == 2))
  2847.     {
  2848.       if (!suppressNameDecoration) TexOutput("{\\b ");
  2849.       currentMember = GetArgChunk();
  2850.     }
  2851.     if (!start && (arg_no == 2))
  2852.     {
  2853.       if (!suppressNameDecoration) TexOutput("}");
  2854.     }
  2855.     
  2856.     if (start && (arg_no == 3))
  2857.       TexOutput("(");
  2858.     if (!start && (arg_no == 3))
  2859.     {
  2860.       TexOutput(")\\li0\\fi0");
  2861.       WriteEnvironmentStyles();
  2862.     }
  2863.     break;
  2864.   }
  2865.   case ltCLIPSFUNC:
  2866.   {
  2867.     if (start && (arg_no == 1))
  2868.       TexOutput("\\pard\\li260\\fi-260{\\b ");
  2869.     if (!start && (arg_no == 1))
  2870.       TexOutput("} ");
  2871.  
  2872.     if (start && (arg_no == 2))
  2873.     {
  2874.       if (!suppressNameDecoration) TexOutput("({\\b ");
  2875.       currentMember = GetArgChunk();
  2876.     }
  2877.     if (!start && (arg_no == 2))
  2878.     {
  2879.       if (!suppressNameDecoration) TexOutput("}");
  2880.     }
  2881.  
  2882.     if (!start && (arg_no == 3))
  2883.     {
  2884.       TexOutput(")\\li0\\fi0");
  2885.       WriteEnvironmentStyles();
  2886.     }
  2887.     break;
  2888.   }
  2889.   case ltPFUNC:
  2890.   {
  2891.     if (start && (arg_no == 1))
  2892.       TexOutput("\\pard\\li260\\fi-260");
  2893.  
  2894.     if (!start && (arg_no == 1))
  2895.       TexOutput(" ");
  2896.  
  2897.     if (start && (arg_no == 2))
  2898.       TexOutput("(*");
  2899.     if (!start && (arg_no == 2))
  2900.       TexOutput(")");
  2901.  
  2902.     if (start && (arg_no == 2))
  2903.       currentMember = GetArgChunk();
  2904.  
  2905.     if (start && (arg_no == 3))
  2906.       TexOutput("(");
  2907.     if (!start && (arg_no == 3))
  2908.     {
  2909.       TexOutput(")\\li0\\fi0");
  2910.       WriteEnvironmentStyles();
  2911.     }
  2912.     break;
  2913.   }
  2914.   case ltPARAM:
  2915.   {
  2916.     if (start && (arg_no == 1))
  2917.       TexOutput("{\\b ");
  2918.     if (!start && (arg_no == 1))
  2919.       TexOutput("}");
  2920.     if (start && (arg_no == 2))
  2921.     {
  2922.       TexOutput("{\\i ");
  2923.     }
  2924.     if (!start && (arg_no == 2))
  2925.     {
  2926.       TexOutput("}");
  2927.     }
  2928.     break;
  2929.   }
  2930.   case ltCPARAM:
  2931.   {
  2932.     if (start && (arg_no == 1))
  2933.       TexOutput("{\\b ");
  2934.     if (!start && (arg_no == 1))
  2935.       TexOutput("} ");  // This is the difference from param - one space!
  2936.     if (start && (arg_no == 2))
  2937.     {
  2938.       TexOutput("{\\i ");
  2939.     }
  2940.     if (!start && (arg_no == 2))
  2941.     {
  2942.       TexOutput("}");
  2943.     }
  2944.     break;
  2945.   }
  2946.   case ltMEMBER:
  2947.   {
  2948.     if (!start && (arg_no == 1))
  2949.       TexOutput(" ");
  2950.  
  2951.     if (start && (arg_no == 2))
  2952.       currentMember = GetArgChunk();
  2953.     break;
  2954.   }
  2955.   case ltREF:
  2956.   {
  2957.     if (start)
  2958.     {
  2959.       char *sec = NULL;
  2960.       
  2961.       char *refName = GetArgData();
  2962.       if (winHelp || !useWord)
  2963.       {
  2964.         if (refName)
  2965.         {
  2966.           TexRef *texRef = FindReference(refName);
  2967.           if (texRef)
  2968.           {
  2969.             sec = texRef->sectionNumber;
  2970.           }
  2971.         }
  2972.         if (sec)
  2973.         {
  2974.           TexOutput(sec);
  2975.         }
  2976.       }
  2977.       else
  2978.       {
  2979.         fprintf(Chapters, "{\\field{\\*\\fldinst  REF %s \\\\* MERGEFORMAT }{\\fldrslt ??}}",
  2980.                 refName);
  2981.       }
  2982.       return FALSE;
  2983.     }
  2984.     break;
  2985.   }
  2986.   case ltHELPREF:
  2987.   case ltHELPREFN:
  2988.   {
  2989.     if (winHelp)
  2990.     {
  2991.         if ((GetNoArgs() - arg_no) == 1)
  2992.         {
  2993.           if (start)
  2994.             TexOutput("{\\uldb ");
  2995.           else
  2996.             TexOutput("}");
  2997.         }
  2998.         if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
  2999.         {
  3000.           if (start)
  3001.             TexOutput("{\\v ");
  3002.           else TexOutput("}");
  3003.         }
  3004.     }
  3005.     else // If a linear document, must resolve the references ourselves
  3006.     {
  3007.       if ((GetNoArgs() - arg_no) == 1)
  3008.       {
  3009.         // In a linear document we display the anchor text in bold plus
  3010.         // the section/figure number.
  3011.         if (start)
  3012.           TexOutput("{\\b ");
  3013.         else
  3014.           TexOutput("}");
  3015.         return TRUE;
  3016.       }
  3017.       else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
  3018.       {
  3019.         if (macroId != ltHELPREFN)
  3020.         {
  3021.           if (start)
  3022.           {
  3023.             TexOutput(" (");
  3024.             char *refName = GetArgData();
  3025.             if (refName)
  3026.             {
  3027.               TexRef *texRef = FindReference(refName);
  3028.               if (texRef)
  3029.               {
  3030.                 TexOutput(texRef->sectionNumber);
  3031.               }
  3032.               else
  3033.               {
  3034.                 TexOutput("??");
  3035.                 sprintf(buf, "Warning: unresolved reference %s.", refName); 
  3036.                 OnInform(buf);
  3037.               }
  3038.             }
  3039.             else TexOutput("??");
  3040.           }
  3041.           else TexOutput(")");
  3042.         }
  3043.         return FALSE;
  3044.       }
  3045.     }
  3046.     break;
  3047.   }
  3048.   case ltPOPREF:
  3049.   {
  3050.     if (winHelp)
  3051.     {
  3052.       if ((GetNoArgs() - arg_no) == 1)
  3053.       {
  3054.         if (start)
  3055.           TexOutput("{\\ul ");
  3056.         else
  3057.           TexOutput("}");
  3058.       }
  3059.       if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
  3060.       {
  3061.         if (start)
  3062.           TexOutput("{\\v ");
  3063.         else TexOutput("}");
  3064.       }
  3065.     }
  3066.     else // A linear document...
  3067.     {
  3068.       if ((GetNoArgs() - arg_no) == 1)
  3069.       {
  3070.         // In a linear document we just display the anchor text in italic
  3071.         if (start)
  3072.           TexOutput("{\\i ");
  3073.         else
  3074.           TexOutput("}");
  3075.         return TRUE;
  3076.       }
  3077.       else return FALSE;
  3078.     }
  3079.     break;
  3080.   }
  3081.   case ltADDCONTENTSLINE:
  3082.   {
  3083.     if (start && !winHelp)
  3084.     {
  3085.       if (arg_no == 2)
  3086.         contentsLineSection = copystring(GetArgData());
  3087.       else if (arg_no == 3)
  3088.         contentsLineValue = copystring(GetArgData());
  3089.       return FALSE;
  3090.     }
  3091.     else return FALSE;
  3092.     break;
  3093.   }
  3094.   case ltIMAGE:
  3095.   case ltPSBOXTO:
  3096.   {
  3097.     static int imageWidth = NULL;
  3098.     static int imageHeight = NULL;
  3099.     
  3100.     if (start && (arg_no == 1))
  3101.     {
  3102.       char *imageDimensions = copystring(GetArgData());
  3103.       char buf1[50];
  3104.       strcpy(buf1, imageDimensions);
  3105.       char *tok1 = strtok(buf1, ";:");
  3106.       char *tok2 = strtok(NULL, ";:");
  3107.       // Convert points to TWIPS (1 twip = 1/20th of point)
  3108.       imageWidth = (int)(20*(tok1 ? ParseUnitArgument(tok1) : 0));
  3109.       imageHeight = (int)(20*(tok2 ? ParseUnitArgument(tok2) : 0));
  3110.     }  
  3111.  
  3112.     if (start && (arg_no == 2 ))
  3113.     {
  3114.       char *filename = copystring(GetArgData());
  3115.       strcpy(buf, filename);
  3116.       StripExtension(buf);
  3117.       strcat(buf, ".bmp");
  3118.       char *f = TexPathList.FindValidPath(buf);
  3119.       if (winHelp || (strcmp(bitmapMethod, "includepicture") == 0)  || (strcmp(bitmapMethod, "import") == 0))
  3120.       {
  3121.         if (!f) // Try for a metafile instead
  3122.         {
  3123.           strcpy(buf, filename);
  3124.           StripExtension(buf);
  3125.           strcat(buf, ".wmf");
  3126.           f = TexPathList.FindValidPath(buf);
  3127.         }
  3128.         if (f)
  3129.         {
  3130.           if (winHelp)
  3131.           {
  3132.             TexOutput("\\{bmc ");
  3133.             TexOutput(FileNameFromPath(f));
  3134.             TexOutput("\\}");
  3135.           }
  3136.           else
  3137.           {
  3138.             // Microsoft Word method
  3139.             if (strcmp(bitmapMethod, "import") == 0)
  3140.               TexOutput("{\\field{\\*\\fldinst IMPORT ");
  3141.             else
  3142.               TexOutput("{\\field{\\*\\fldinst INCLUDEPICTURE ");
  3143.  
  3144.             // Full path appears not to be valid!
  3145.             TexOutput(FileNameFromPath(f));
  3146. /*
  3147.             int len = strlen(f);
  3148.             char smallBuf[2]; smallBuf[1] = 0;
  3149.             for (int i = 0; i < len; i++)
  3150.             {
  3151.               smallBuf[0] = f[i];
  3152.               TexOutput(smallBuf);
  3153.               if (smallBuf[0] == '\\')
  3154.                 TexOutput(smallBuf);
  3155.             }
  3156. */
  3157.             TexOutput("}{\\fldrslt PRESS F9 TO FORMAT PICTURE}}");
  3158.           }
  3159.         }
  3160.         else
  3161.         {
  3162.           TexOutput("[No BMP or MF for image file ");
  3163.           TexOutput(filename);
  3164.           TexOutput("]");
  3165.           sprintf(buf, "Warning: could not find a BMP or MF equivalent for %s.", filename);
  3166.           OnInform(buf);
  3167.         }
  3168.       }
  3169.       else
  3170.       {
  3171.           if (f)
  3172.           {
  3173.             FILE *fd = fopen(f, "rb");
  3174.             if (OutputBitmapHeader(fd, winHelp))
  3175.               OutputBitmapData(fd);
  3176.             else
  3177.             {
  3178.               sprintf(buf, "Could not read bitmap %s.\nMay be in wrong format (needs RGB-encoded Windows BMP).", f);
  3179.               OnError(buf);
  3180.             }
  3181.             fclose(fd);
  3182.           }
  3183.           else // Try for a metafile instead
  3184.           {
  3185. #ifdef wx_msw
  3186.             strcpy(buf, filename);
  3187.             StripExtension(buf);
  3188.             strcat(buf, ".wmf");
  3189.             f = TexPathList.FindValidPath(buf);
  3190.             if (f)
  3191.             {
  3192.   //            HFILE handle = _lopen(f, READ);
  3193.               FILE *fd = fopen(f, "rb");
  3194.               if (OutputMetafileHeader(fd, winHelp, imageWidth, imageHeight))
  3195.               {
  3196.                 OutputMetafileData(fd);
  3197.               }
  3198.               else
  3199.               {
  3200.                 sprintf(buf, "Could not read metafile %s. Perhaps it's not a placeable metafile?", f);
  3201.                 OnError(buf);
  3202.               }
  3203.               fclose(fd);
  3204.             }
  3205.             else
  3206.             {
  3207. #endif            
  3208.               TexOutput("[No BMP or WMF for image file ");
  3209.               TexOutput(filename);
  3210.               TexOutput("]");
  3211.               sprintf(buf, "Warning: could not find a BMP or WMF equivalent for %s.", filename);
  3212.               OnInform(buf);
  3213. #ifdef wx_msw            
  3214.             }
  3215. #endif
  3216.         }
  3217.       }
  3218.       return FALSE;
  3219.     }
  3220.     else
  3221.       return FALSE;
  3222.     break;
  3223.   }
  3224.   case ltTABULAR:
  3225.   case ltSUPERTABULAR:
  3226.   {
  3227.     if (arg_no == 1)
  3228.     {
  3229.       if (start)
  3230.       {
  3231.         currentRowNumber = 0;
  3232.         inTabular = TRUE;
  3233.         startRows = TRUE;
  3234.         tableVerticalLineLeft = FALSE;
  3235.         tableVerticalLineRight = FALSE;
  3236.         int currentWidth = 0;
  3237.  
  3238.         char *alignString = copystring(GetArgData());
  3239.         ParseTableArgument(alignString);
  3240.  
  3241. //        TexOutput("\\trowd\\trgaph108\\trleft-108");
  3242.         TexOutput("\\trowd\\trgaph108");
  3243.  
  3244.         // Write the first row formatting for compatibility
  3245.         // with standard Latex
  3246.         if (compatibilityMode)
  3247.         {
  3248.           for (int i = 0; i < noColumns; i++)
  3249.           {
  3250.             currentWidth += TableData[i].width;
  3251.             sprintf(buf, "\\cellx%d", currentWidth);
  3252.             TexOutput(buf);
  3253.           }
  3254.           TexOutput("\\pard\\intbl\n");
  3255.         }
  3256.  
  3257.         return FALSE;
  3258.       }
  3259.     }
  3260.     else if (arg_no == 2 && !start)
  3261.     {
  3262.       TexOutput("\\pard\n");
  3263.       WriteEnvironmentStyles();
  3264.       inTabular = FALSE;
  3265.     }
  3266.     break;
  3267.   }
  3268.  
  3269.   case ltQUOTE:
  3270.   case ltVERSE:
  3271.   {
  3272.     if (start)
  3273.     {
  3274.       TexOutput("\\li360\n");
  3275.       forbidParindent ++;
  3276.       PushEnvironmentStyle("\\li360");
  3277.     }
  3278.     else
  3279.     {
  3280.       forbidParindent --;
  3281.       PopEnvironmentStyle();
  3282.       OnMacro(ltPAR, 0, TRUE);
  3283.       OnMacro(ltPAR, 0, FALSE);
  3284.     }
  3285.     break;
  3286.   }
  3287.   case ltQUOTATION:
  3288.   {
  3289.     if (start)
  3290.     {
  3291.       TexOutput("\\li360\n");
  3292.       PushEnvironmentStyle("\\li360");
  3293.     }
  3294.     else
  3295.     {
  3296.       PopEnvironmentStyle();
  3297.       OnMacro(ltPAR, 0, TRUE);
  3298.       OnMacro(ltPAR, 0, FALSE);
  3299.     }
  3300.     break;
  3301.   }
  3302.   case ltBOXIT:
  3303.   case ltFRAMEBOX:
  3304.   case ltFBOX:
  3305.   case ltNORMALBOX:
  3306.   case ltNORMALBOXD:
  3307.   {
  3308.     if (start)
  3309.     {
  3310.       sprintf(buf, "\\box\\trgaph108%s\n", ((macroId == ltNORMALBOXD) ? "\\brdrdb" : "\\brdrs"));
  3311.       TexOutput(buf);
  3312.       PushEnvironmentStyle(buf);
  3313.     }
  3314.     else
  3315.     {
  3316.       PopEnvironmentStyle();
  3317.       OnMacro(ltPAR, 0, TRUE);
  3318.       OnMacro(ltPAR, 0, FALSE);
  3319.     }
  3320.     break;
  3321.   }
  3322.   case ltHELPFONTSIZE:
  3323.   {
  3324.     if (start)
  3325.     {
  3326.       char *data = GetArgData();
  3327.       if (strcmp(data, "10") == 0)
  3328.         SetFontSizes(10);
  3329.       else if (strcmp(data, "11") == 0)
  3330.         SetFontSizes(11);
  3331.       else if (strcmp(data, "12") == 0)
  3332.         SetFontSizes(12);
  3333.       sprintf(buf, "\\fs%d\n", normalFont*2);
  3334.       TexOutput(buf);
  3335.       TexOutput(buf);
  3336.       return FALSE;
  3337.     }
  3338.     break;
  3339.   }
  3340.   case ltHELPFONTFAMILY:
  3341.   {
  3342.     if (start)
  3343.     {
  3344.       char *data = GetArgData();
  3345.       if (strcmp(data, "Swiss") == 0)
  3346.         TexOutput("\\f2\n");
  3347.       else if (strcmp(data, "Symbol") == 0)
  3348.         TexOutput("\\f1\n");
  3349.       else if (strcmp(data, "Times") == 0)
  3350.         TexOutput("\\f0\n");
  3351.  
  3352.       return FALSE;
  3353.     }
  3354.     break;
  3355.   }
  3356.   case ltPARINDENT:
  3357.   {
  3358.     if (start && arg_no == 1)
  3359.     {
  3360.       char *data = GetArgData();
  3361.       ParIndent = ParseUnitArgument(data);
  3362.       if (ParIndent == 0 || forbidParindent == 0)
  3363.       {
  3364.         sprintf(buf, "\\fi%d\n", ParIndent*20);
  3365.         TexOutput(buf);
  3366.       }
  3367.       return FALSE;
  3368.     }
  3369.     break;
  3370.   }
  3371.   case ltITEM:
  3372.   {
  3373.     if (start && IsArgOptional())
  3374.     {
  3375.       descriptionItemArg = GetArgChunk();
  3376.       return FALSE;
  3377.     }
  3378.     break;
  3379.   }
  3380.   case ltTWOCOLITEM:
  3381.   case ltTWOCOLITEMRULED:
  3382.   {
  3383.     switch (arg_no)
  3384.     {
  3385.       case 1:
  3386.       {
  3387.         if (!start)
  3388.           TexOutput("\\tab ");
  3389.         break;
  3390.       }
  3391.       case 2:
  3392.       {
  3393.         if (!start)
  3394.         {
  3395.           if (macroId == ltTWOCOLITEMRULED)
  3396.             TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
  3397.           TexOutput("\\par\\pard\n");
  3398.           issuedNewParagraph = TRUE;
  3399.           WriteEnvironmentStyles();
  3400.         }
  3401.         break;
  3402.       }
  3403.     }
  3404.     return TRUE;
  3405.     break;
  3406.   }
  3407.   /*
  3408.    * Accents
  3409.    *
  3410.    */
  3411.   case ltACCENT_GRAVE:
  3412.   {
  3413.     if (start)
  3414.     {
  3415.       char *val = GetArgData();
  3416.       if (val)
  3417.       {
  3418.         switch (val[0])
  3419.         {
  3420.           case 'a':
  3421.            TexOutput("\\'e0");
  3422.            break;
  3423.           case 'e':
  3424.            TexOutput("\\'e8");
  3425.            break;
  3426.           case 'i':
  3427.            TexOutput("\\'ec");
  3428.            break;
  3429.           case 'o':
  3430.            TexOutput("\\'f2");
  3431.            break;
  3432.           case 'u':
  3433.            TexOutput("\\'f9");
  3434.            break;
  3435.           case 'A':
  3436.            TexOutput("\\'c0");
  3437.            break;
  3438.           case 'E':
  3439.            TexOutput("\\'c8");
  3440.            break;
  3441.           case 'I':
  3442.            TexOutput("\\'cc");
  3443.            break;
  3444.           case 'O':
  3445.            TexOutput("\\'d2");
  3446.            break;
  3447.           case 'U':
  3448.            TexOutput("\\'d9");
  3449.            break;
  3450.           default:
  3451.            break;
  3452.         }
  3453.       }
  3454.     }
  3455.     return FALSE;
  3456.     break;
  3457.   }
  3458.   case ltACCENT_ACUTE:
  3459.   {
  3460.     if (start)
  3461.     {
  3462.       char *val = GetArgData();
  3463.       if (val)
  3464.       {
  3465.         switch (val[0])
  3466.         {
  3467.           case 'a':
  3468.            TexOutput("\\'e1");
  3469.            break;
  3470.           case 'e':
  3471.            TexOutput("\\'e9");
  3472.            break;
  3473.           case 'i':
  3474.            TexOutput("\\'ed");
  3475.            break;
  3476.           case 'o':
  3477.            TexOutput("\\'f3");
  3478.            break;
  3479.           case 'u':
  3480.            TexOutput("\\'fa");
  3481.            break;
  3482.           case 'y':
  3483.            TexOutput("\\'fd");
  3484.            break;
  3485.           case 'A':
  3486.            TexOutput("\\'c1");
  3487.            break;
  3488.           case 'E':
  3489.            TexOutput("\\'c9");
  3490.            break;
  3491.           case 'I':
  3492.            TexOutput("\\'cd");
  3493.            break;
  3494.           case 'O':
  3495.            TexOutput("\\'d3");
  3496.            break;
  3497.           case 'U':
  3498.            TexOutput("\\'da");
  3499.            break;
  3500.           case 'Y':
  3501.            TexOutput("\\'dd");
  3502.            break;
  3503.           default:
  3504.            break;
  3505.         }
  3506.       }
  3507.     }
  3508.     return FALSE;
  3509.     break;
  3510.   }
  3511.   case ltACCENT_CARET:
  3512.   {
  3513.     if (start)
  3514.     {
  3515.       char *val = GetArgData();
  3516.       if (val)
  3517.       {
  3518.         switch (val[0])
  3519.         {
  3520.           case 'a':
  3521.            TexOutput("\\'e2");
  3522.            break;
  3523.           case 'e':
  3524.            TexOutput("\\'ea");
  3525.            break;
  3526.           case 'i':
  3527.            TexOutput("\\'ee");
  3528.            break;
  3529.           case 'o':
  3530.            TexOutput("\\'f4");
  3531.            break;
  3532.           case 'u':
  3533.            TexOutput("\\'fb");
  3534.            break;
  3535.           case 'A':
  3536.            TexOutput("\\'c2");
  3537.            break;
  3538.           case 'E':
  3539.            TexOutput("\\'ca");
  3540.            break;
  3541.           case 'I':
  3542.            TexOutput("\\'ce");
  3543.            break;
  3544.           case 'O':
  3545.            TexOutput("\\'d4");
  3546.            break;
  3547.           case 'U':
  3548.            TexOutput("\\'db");
  3549.            break;
  3550.           default:
  3551.            break;
  3552.         }
  3553.       }
  3554.     }
  3555.     return FALSE;
  3556.     break;
  3557.   }
  3558.   case ltACCENT_TILDE:
  3559.   {
  3560.     if (start)
  3561.     {
  3562.       char *val = GetArgData();
  3563.       if (val)
  3564.       {
  3565.         switch (val[0])
  3566.         {
  3567.           case 'a':
  3568.            TexOutput("\\'e3");
  3569.            break;
  3570.           case 'n':
  3571.            TexOutput("\\'f1");
  3572.            break;
  3573.           case 'o':
  3574.            TexOutput("\\'f5");
  3575.            break;
  3576.           case 'A':
  3577.            TexOutput("\\'c3");
  3578.            break;
  3579.           case 'N':
  3580.            TexOutput("\\'d1");
  3581.            break;
  3582.           case 'O':
  3583.            TexOutput("\\'d5");
  3584.            break;
  3585.           default:
  3586.            break;
  3587.         }
  3588.       }
  3589.     }
  3590.     return FALSE;
  3591.     break;
  3592.   }
  3593.   case ltACCENT_UMLAUT:
  3594.   {
  3595.     if (start)
  3596.     {
  3597.       char *val = GetArgData();
  3598.       if (val)
  3599.       {
  3600.         switch (val[0])
  3601.         {
  3602.           case 'a':
  3603.            TexOutput("\\'e4");
  3604.            break;
  3605.           case 'e':
  3606.            TexOutput("\\'eb");
  3607.            break;
  3608.           case 'i':
  3609.            TexOutput("\\'ef");
  3610.            break;
  3611.           case 'o':
  3612.            TexOutput("\\'f6");
  3613.            break;
  3614.           case 'u':
  3615.            TexOutput("\\'fc");
  3616.            break;
  3617.           case 'y':
  3618.            TexOutput("\\'ff");
  3619.            break;
  3620.           case 'A':
  3621.            TexOutput("\\'c4");
  3622.            break;
  3623.           case 'E':
  3624.            TexOutput("\\'cb");
  3625.            break;
  3626.           case 'I':
  3627.            TexOutput("\\'cf");
  3628.            break;
  3629.           case 'O':
  3630.            TexOutput("\\'d6");
  3631.            break;
  3632.           case 'U':
  3633.            TexOutput("\\'dc");
  3634.            break;
  3635.           case 'Y':
  3636.            TexOutput("\\'df");
  3637.            break;
  3638.           default:
  3639.            break;
  3640.         }
  3641.       }
  3642.     }
  3643.     return FALSE;
  3644.     break;
  3645.   }
  3646.   case ltACCENT_DOT:
  3647.   {
  3648.     if (start)
  3649.     {
  3650.       char *val = GetArgData();
  3651.       if (val)
  3652.       {
  3653.         switch (val[0])
  3654.         {
  3655.           case 'a':
  3656.            TexOutput("\\'e5");
  3657.            break;
  3658.           case 'A':
  3659.            TexOutput("\\'c5");
  3660.            break;
  3661.           default:
  3662.            break;
  3663.         }
  3664.       }
  3665.     }
  3666.     return FALSE;
  3667.     break;
  3668.   }
  3669.   case ltACCENT_CADILLA:
  3670.   {
  3671.     if (start)
  3672.     {
  3673.       char *val = GetArgData();
  3674.       if (val)
  3675.       {
  3676.         switch (val[0])
  3677.         {
  3678.           case 'c':
  3679.            TexOutput("\\'e7");
  3680.            break;
  3681.           case 'C':
  3682.            TexOutput("\\'c7");
  3683.            break;
  3684.           default:
  3685.            break;
  3686.         }
  3687.       }
  3688.     }
  3689.     return FALSE;
  3690.     break;
  3691.   }
  3692.   case ltFOOTNOTE:
  3693.   {
  3694.     static char *helpTopic = NULL;
  3695.     static FILE *savedOutput = NULL;
  3696.     if (winHelp)
  3697.     {
  3698.       if (arg_no == 1)
  3699.       {
  3700.         if (start)
  3701.         {
  3702.           OnInform("Consider using \\footnotepopup instead of \\footnote.");
  3703.           footnoteCount ++;
  3704.           char footBuf[20];
  3705.           sprintf(footBuf, "(%d)", footnoteCount);
  3706.  
  3707.           TexOutput(" {\\ul ");
  3708.           TexOutput(footBuf);
  3709.           TexOutput("}");
  3710.           helpTopic = FindTopicName(NULL);
  3711.           TexOutput("{\\v ");
  3712.           TexOutput(helpTopic);
  3713.           TexOutput("}");
  3714.  
  3715.           fprintf(Popups, "\\page\n");
  3716. //          fprintf(Popups, "\n${\\footnote }"); // No title
  3717.           fprintf(Popups, "\n#{\\footnote %s}\n", helpTopic);
  3718.           fprintf(Popups, "+{\\footnote %s}\n", GetBrowseString());
  3719.           savedOutput = CurrentOutput1;
  3720.           SetCurrentOutput(Popups);
  3721.     }
  3722.     else
  3723.     {
  3724.           SetCurrentOutput(savedOutput);
  3725.     }
  3726.     return TRUE;
  3727.       }
  3728.       return TRUE;
  3729.     }
  3730.     else
  3731.     {
  3732.       if (start)
  3733.       {
  3734.         TexOutput(" {\\super \\chftn{\\footnote \\fs20 {\\super \\chftn}", TRUE);
  3735.       }
  3736.       else
  3737.       {
  3738.         TexOutput("}}", TRUE);
  3739.       }
  3740.       return TRUE;
  3741.     }
  3742.     break;
  3743.   }
  3744.   case ltFOOTNOTEPOPUP:
  3745.   {
  3746.     static char *helpTopic = NULL;
  3747.     static FILE *savedOutput = NULL;
  3748.     if (winHelp)
  3749.     {
  3750.       if (arg_no == 1)
  3751.       {
  3752.         if (start)
  3753.         {
  3754.           TexOutput("{\\ul ");
  3755.     }
  3756.     else TexOutput("}");
  3757.     return TRUE;
  3758.       }
  3759.       else if (arg_no == 2)
  3760.       {
  3761.         if (start)
  3762.         {
  3763.           helpTopic = FindTopicName(NULL);
  3764.           TexOutput("{\\v ");
  3765.           TexOutput(helpTopic);
  3766.           TexOutput("}");
  3767.  
  3768.           fprintf(Popups, "\\page\n");
  3769. //          fprintf(Popups, "\n${\\footnote }"); // No title
  3770.           fprintf(Popups, "\n#{\\footnote %s}\n", helpTopic);
  3771.           fprintf(Popups, "+{\\footnote %s}\n", GetBrowseString());
  3772.           savedOutput = CurrentOutput1;
  3773.           SetCurrentOutput(Popups);
  3774.         }
  3775.         else
  3776.         {
  3777.           SetCurrentOutput(savedOutput);
  3778.         }
  3779.         return TRUE;
  3780.       }
  3781.     }
  3782.     else
  3783.     {
  3784.       if (arg_no == 1)
  3785.         return TRUE;
  3786.       if (start)
  3787.       {
  3788.         TexOutput(" {\\super \\chftn{\\footnote \\fs20 {\\super \\chftn}", TRUE);
  3789.       }
  3790.       else
  3791.       {
  3792.         TexOutput("}}", TRUE);
  3793.       }
  3794.       return TRUE;
  3795.     }
  3796.     break;
  3797.   }
  3798.   case ltFANCYPLAIN:
  3799.   {
  3800.     if (start && (arg_no == 1))
  3801.       return FALSE;
  3802.     else
  3803.       return TRUE;
  3804.     break;
  3805.   }
  3806.   case ltSETHEADER:
  3807.   {
  3808.     if (start)
  3809.       forbidResetPar ++;
  3810.     else
  3811.       forbidResetPar --;
  3812.  
  3813.     if (winHelp) return FALSE;
  3814.     if (start)
  3815.     {
  3816.       switch (arg_no)
  3817.       {
  3818.         case 1:
  3819.           LeftHeaderEven = GetArgChunk();
  3820.           if (strlen(GetArgData(LeftHeaderEven)) == 0)
  3821.             LeftHeaderEven = NULL;
  3822.           break;
  3823.         case 2:
  3824.           CentreHeaderEven = GetArgChunk();
  3825.           if (strlen(GetArgData(CentreHeaderEven)) == 0)
  3826.             CentreHeaderEven = NULL;
  3827.           break;
  3828.         case 3:
  3829.           RightHeaderEven = GetArgChunk();
  3830.           if (strlen(GetArgData(RightHeaderEven)) == 0)
  3831.             RightHeaderEven = NULL;
  3832.           break;
  3833.         case 4:
  3834.           LeftHeaderOdd = GetArgChunk();
  3835.           if (strlen(GetArgData(LeftHeaderOdd)) == 0)
  3836.             LeftHeaderOdd = NULL;
  3837.           break;
  3838.         case 5:
  3839.           CentreHeaderOdd = GetArgChunk();
  3840.           if (strlen(GetArgData(CentreHeaderOdd)) == 0)
  3841.             CentreHeaderOdd = NULL;
  3842.           break;
  3843.         case 6:
  3844.           RightHeaderOdd = GetArgChunk();
  3845.           if (strlen(GetArgData(RightHeaderOdd)) == 0)
  3846.             RightHeaderOdd = NULL;
  3847.           OutputRTFHeaderCommands();
  3848.           break;
  3849.         default:
  3850.           break;
  3851.       }
  3852.     }
  3853.     return FALSE;
  3854.     break;
  3855.   }
  3856.   case ltSETFOOTER:
  3857.   {
  3858.     if (start)
  3859.       forbidResetPar ++;
  3860.     else
  3861.       forbidResetPar --;
  3862.  
  3863.     if (winHelp) return FALSE;
  3864.     if (start)
  3865.     {
  3866.       switch (arg_no)
  3867.       {
  3868.         case 1:
  3869.           LeftFooterEven = GetArgChunk();
  3870.           if (strlen(GetArgData(LeftFooterEven)) == 0)
  3871.             LeftFooterEven = NULL;
  3872.           break;
  3873.         case 2:
  3874.           CentreFooterEven = GetArgChunk();
  3875.           if (strlen(GetArgData(CentreFooterEven)) == 0)
  3876.             CentreFooterEven = NULL;
  3877.           break;
  3878.         case 3:
  3879.           RightFooterEven = GetArgChunk();
  3880.           if (strlen(GetArgData(RightFooterEven)) == 0)
  3881.             RightFooterEven = NULL;
  3882.           break;
  3883.         case 4:
  3884.           LeftFooterOdd = GetArgChunk();
  3885.           if (strlen(GetArgData(LeftFooterOdd)) == 0)
  3886.             LeftFooterOdd = NULL;
  3887.           break;
  3888.         case 5:
  3889.           CentreFooterOdd = GetArgChunk();
  3890.           if (strlen(GetArgData(CentreFooterOdd)) == 0)
  3891.             CentreFooterOdd = NULL;
  3892.           break;
  3893.         case 6:
  3894.           RightFooterOdd = GetArgChunk();
  3895.           if (strlen(GetArgData(RightFooterOdd)) == 0)
  3896.             RightFooterOdd = NULL;
  3897.           OutputRTFFooterCommands();
  3898.           break;
  3899.         default:
  3900.           break;
  3901.       }
  3902.     }
  3903.     return FALSE;
  3904.     break;
  3905.   }
  3906.   case ltMARKRIGHT:
  3907.   {
  3908.     if (winHelp) return FALSE;
  3909.     // Fake a SetHeader command
  3910.     if (start)
  3911.     {
  3912.       LeftHeaderOdd = NULL;
  3913.       CentreHeaderOdd = NULL;
  3914.       RightHeaderOdd = NULL;
  3915.       LeftHeaderEven = NULL;
  3916.       CentreHeaderEven = NULL;
  3917.       RightHeaderEven = NULL;
  3918.       OnInform("Consider using setheader/setfooter rather than markright.");
  3919.     }
  3920.     RTFOnArgument(ltSETHEADER, 4, start);
  3921.     if (!start)
  3922.       OutputRTFHeaderCommands();
  3923.     return FALSE;
  3924.     break;
  3925.   }
  3926.   case ltMARKBOTH:
  3927.   {
  3928.     if (winHelp) return FALSE;
  3929.     // Fake a SetHeader command
  3930.     switch (arg_no)
  3931.     {
  3932.       case 1:
  3933.       {
  3934.         if (start)
  3935.         {
  3936.           LeftHeaderOdd = NULL;
  3937.           CentreHeaderOdd = NULL;
  3938.           RightHeaderOdd = NULL;
  3939.           LeftHeaderEven = NULL;
  3940.           CentreHeaderEven = NULL;
  3941.           RightHeaderEven = NULL;
  3942.           OnInform("Consider using setheader/setfooter rather than markboth.");
  3943.         }
  3944.         return RTFOnArgument(ltSETHEADER, 1, start);
  3945.         break;
  3946.       }
  3947.       case 2:
  3948.       {
  3949.         RTFOnArgument(ltSETHEADER, 4, start);
  3950.         if (!start)
  3951.           OutputRTFHeaderCommands();
  3952.         return FALSE;
  3953.         break;
  3954.       }
  3955.     }
  3956.     break;
  3957.   }
  3958.   case ltPAGENUMBERING:
  3959.   {
  3960.     if (start)
  3961.       forbidResetPar ++;
  3962.     else
  3963.       forbidResetPar --;
  3964.  
  3965.     if (winHelp) return FALSE;
  3966.     if (start)
  3967.     {
  3968.       TexOutput("\\pgnrestart");
  3969.       char *data = GetArgData();
  3970.       if (currentNumberStyle) delete[] currentNumberStyle;
  3971.       currentNumberStyle = copystring(data);
  3972.       OutputNumberStyle(currentNumberStyle);
  3973.       
  3974.       TexOutput("\n");
  3975.     }
  3976.     return FALSE;
  3977.     break;
  3978.   }
  3979.   case ltTWOCOLUMN:
  3980.   {
  3981.     if (winHelp) return FALSE;
  3982.     if (start)
  3983.       return TRUE;
  3984.     break;
  3985.   }
  3986.   case ltITEMSEP:
  3987.   {
  3988.     if (start)
  3989.     {
  3990.       char *val = GetArgData();
  3991.       currentItemSep = ParseUnitArgument(val);
  3992.       return FALSE;
  3993.     }
  3994.     break;
  3995.   }
  3996.   case ltEVENSIDEMARGIN:
  3997.   {
  3998.     return FALSE;
  3999.     break;
  4000.   }
  4001.   case ltODDSIDEMARGIN:
  4002.   {
  4003.     if (start)
  4004.     {
  4005.       char *val = GetArgData();
  4006.       int twips = (int)(20*ParseUnitArgument(val));
  4007.       // Add an inch since in LaTeX it's specified minus an inch
  4008.       twips += 1440;
  4009.       CurrentLeftMarginOdd = twips;
  4010.       sprintf(buf, "\\margl%d\n", twips);
  4011.       TexOutput(buf);
  4012.  
  4013.       CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
  4014.     }
  4015.     return FALSE;
  4016.   }
  4017.   case ltMARGINPARWIDTH:
  4018.   {
  4019.     if (start)
  4020.     {
  4021.       char *val = GetArgData();
  4022.       int twips = (int)(20*ParseUnitArgument(val));
  4023.       CurrentMarginParWidth = twips;
  4024.     }
  4025.     return FALSE;
  4026.   }
  4027.   case ltMARGINPARSEP:
  4028.   {
  4029.     if (start)
  4030.     {
  4031.       char *val = GetArgData();
  4032.       int twips = (int)(20*ParseUnitArgument(val));
  4033.       CurrentMarginParSep = twips;
  4034.       CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
  4035.     }
  4036.     return FALSE;
  4037.   }
  4038.   case ltTEXTWIDTH:
  4039.   {
  4040.     if (start)
  4041.     {
  4042.       char *val = GetArgData();
  4043.       int twips = (int)(20*ParseUnitArgument(val));
  4044.       CurrentTextWidth = twips;
  4045.  
  4046.       // Need to set an implicit right margin
  4047.       CurrentRightMarginOdd = PageWidth - CurrentTextWidth - CurrentLeftMarginOdd;
  4048.       CurrentRightMarginEven = PageWidth - CurrentTextWidth - CurrentLeftMarginEven;
  4049.       CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
  4050.       sprintf(buf, "\\margr%d\n", CurrentRightMarginOdd);
  4051.       TexOutput(buf);
  4052.     }
  4053.     return FALSE;
  4054.   }
  4055.   case ltMARGINPAR:
  4056.   case ltMARGINPARODD:
  4057.   {
  4058.     if (start)
  4059.     {
  4060.       if (winHelp)
  4061.       {
  4062.         TexOutput("\\box\n");
  4063.         PushEnvironmentStyle("\\box");
  4064.       }
  4065.       else
  4066.       {
  4067.         sprintf(buf, "\\phpg\\posx%d\\absw%d\n", CurrentMarginParX, CurrentMarginParWidth);
  4068.         TexOutput(buf);
  4069.       }
  4070.       return TRUE;
  4071.     }
  4072.     else
  4073.     {
  4074.       if (winHelp)
  4075.       {
  4076.         TexOutput("\\par\\pard\n");
  4077.         PopEnvironmentStyle();
  4078.         WriteEnvironmentStyles();
  4079.       }
  4080.       else
  4081.         TexOutput("\\par\\pard\n");
  4082.       issuedNewParagraph = TRUE;
  4083.     }
  4084.     return FALSE;
  4085.   }
  4086.   case ltMARGINPAREVEN:
  4087.   {
  4088.     if (start)
  4089.     {
  4090.       if (winHelp)
  4091.       {
  4092.         TexOutput("\\box\n");
  4093.         PushEnvironmentStyle("\\box");
  4094.       }
  4095.       else
  4096.       {
  4097.         if (mirrorMargins)
  4098.         {
  4099.           // Have to calculate what the margins are changed to in WfW margin
  4100.           // mirror mode, on an even (left-hand) page.
  4101.           int x = PageWidth - CurrentRightMarginOdd - CurrentMarginParWidth - CurrentMarginParSep
  4102.                     - CurrentTextWidth + GutterWidth;
  4103.           sprintf(buf, "\\phpg\\posx%d\\absw%d\n", x, CurrentMarginParWidth);
  4104.           TexOutput(buf);
  4105.         }
  4106.         else
  4107.         {
  4108.           sprintf(buf, "\\phpg\\posx%d\\absw%d\n", CurrentMarginParX, CurrentMarginParWidth);
  4109.           TexOutput(buf);
  4110.         }
  4111.       }
  4112.       return TRUE;
  4113.     }
  4114.     else
  4115.     {
  4116.       if (winHelp)
  4117.       {
  4118.         TexOutput("\\par\\pard\n");
  4119.         PopEnvironmentStyle();
  4120.         WriteEnvironmentStyles();
  4121.       }
  4122.       else
  4123.         issuedNewParagraph = TRUE;
  4124.       TexOutput("\\par\\pard\n");
  4125.     }
  4126.     return FALSE;
  4127.   }
  4128.   case ltTWOCOLWIDTHA:
  4129.   {
  4130.     if (start)
  4131.     {
  4132.       char *val = GetArgData();
  4133.       int twips = (int)(20*ParseUnitArgument(val));
  4134.       TwoColWidthA = twips;
  4135.     }
  4136.     return FALSE;
  4137.     break;
  4138.   }
  4139.   case ltTWOCOLWIDTHB:
  4140.   {
  4141.     if (start)
  4142.     {
  4143.       char *val = GetArgData();
  4144.       int twips = (int)(20*ParseUnitArgument(val));
  4145.       TwoColWidthB = twips;
  4146.     }
  4147.     return FALSE;
  4148.     break;
  4149.   }
  4150.   case ltROW:
  4151.   case ltRULEDROW:
  4152.   {
  4153.     if (start)
  4154.     {
  4155.       int currentWidth = 0;
  4156.  
  4157.       if (!compatibilityMode || (currentRowNumber > 0))
  4158.       {
  4159.       TexOutput("\\pard\\intbl");
  4160.  
  4161.       if (macroId == ltRULEDROW)
  4162.         ruleBottom = 1;
  4163.       for (int i = 0; i < noColumns; i++)
  4164.       {
  4165.         currentWidth += TableData[i].width;
  4166.         if (ruleTop == 1)
  4167.         {
  4168.           TexOutput("\\clbrdrt\\brdrs\\brdrw15");
  4169.         }
  4170.         else if (ruleTop > 1)
  4171.         {
  4172.           TexOutput("\\clbrdrt\\brdrdb\\brdrw15");
  4173.         }
  4174.         if (ruleBottom == 1)
  4175.         {
  4176.           TexOutput("\\clbrdrb\\brdrs\\brdrw15");
  4177.         }
  4178.         else if (ruleBottom > 1)
  4179.         {
  4180.           TexOutput("\\clbrdrb\\brdrdb\\brdrw15");
  4181.         }
  4182.  
  4183.         if (TableData[i].rightBorder)
  4184.           TexOutput("\\clbrdrr\\brdrs\\brdrw15");
  4185.  
  4186.         if (TableData[i].leftBorder)
  4187.           TexOutput("\\clbrdrl\\brdrs\\brdrw15");
  4188.           
  4189.         sprintf(buf, "\\cellx%d", currentWidth);
  4190.         TexOutput(buf);
  4191.       }
  4192.       TexOutput("\\pard\\intbl\n");
  4193.       }
  4194.       ruleTop = 0;
  4195.       ruleBottom = 0;
  4196.       currentRowNumber ++;
  4197.       return TRUE;
  4198.     }
  4199.     else
  4200.     {
  4201. //      TexOutput("\\cell\\row\\trowd\\trgaph108\\trleft-108\n");
  4202.       TexOutput("\\cell\\row\\trowd\\trgaph108\n");
  4203.     }
  4204.     break;
  4205.   }
  4206.   case ltMULTICOLUMN:
  4207.   {
  4208.     static int noMultiColumns = 0;
  4209.     if (start)
  4210.     {
  4211.       switch (arg_no)
  4212.       {
  4213.         case 1:
  4214.         {
  4215.           noMultiColumns = atoi(GetArgData());
  4216.           return FALSE;
  4217.           break;
  4218.         }
  4219.         case 2:
  4220.         {
  4221.           return FALSE;
  4222.         }
  4223.         case 3:
  4224.         {
  4225.           return TRUE;
  4226.         }
  4227.       }
  4228.     }
  4229.     else
  4230.     {
  4231.       if (arg_no == 3)
  4232.       {
  4233.         for (int i = 1; i < noMultiColumns; i ++)
  4234.           TexOutput("\\cell");
  4235.       }
  4236.     }
  4237.     break;
  4238.   }
  4239.   case ltINDENTED:
  4240.   {
  4241.     if (start && (arg_no == 1))
  4242.     {
  4243. //      indentLevel ++;
  4244. //      TexOutput("\\fi0\n");
  4245.       int oldIndent = 0;
  4246.       wxNode *node = itemizeStack.First();
  4247.       if (node)
  4248.         oldIndent = ((ItemizeStruc *)node->Data())->indentation;
  4249.  
  4250.       int indentValue = 20*ParseUnitArgument(GetArgData());
  4251.       int indentSize = indentValue + oldIndent;
  4252.  
  4253.       ItemizeStruc *struc = new ItemizeStruc(LATEX_INDENT, indentSize);
  4254.       itemizeStack.Insert(struc);
  4255.       
  4256.       sprintf(buf, "\\tx%d\\li%d ", indentSize, indentSize);
  4257.       PushEnvironmentStyle(buf);
  4258.       TexOutput(buf);
  4259.       return FALSE;
  4260.     }
  4261.     if (!start && (arg_no == 2))
  4262.     {
  4263.       PopEnvironmentStyle();
  4264.       if (itemizeStack.First())
  4265.       {
  4266.         ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
  4267.         delete struc;
  4268.         delete itemizeStack.First();
  4269.       }
  4270.       if (itemizeStack.Number() == 0)
  4271.       {
  4272.         TexOutput("\\par\\pard\n");
  4273.         issuedNewParagraph = TRUE;
  4274.         WriteEnvironmentStyles();
  4275.       }
  4276.     }
  4277.     return TRUE;
  4278.     break;
  4279.   }
  4280. /*
  4281.   case ltSIZEDBOX:
  4282.   case ltSIZEDBOXD:
  4283.   {
  4284.     if (start && (arg_no == 1))
  4285.     {
  4286.       int oldIndent = 0;
  4287.       wxNode *node = itemizeStack.First();
  4288.       if (node)
  4289.         oldIndent = ((ItemizeStruc *)node->Data())->indentation;
  4290.  
  4291.       int boxWidth = 20*ParseUnitArgument(GetArgData());
  4292.  
  4293.       int indentValue = (int)((CurrentTextWidth - oldIndent - boxWidth)/2.0);
  4294.       int indentSize = indentValue + oldIndent;
  4295.       int indentSizeRight = indentSize + boxWidth;
  4296.  
  4297.       ItemizeStruc *struc = new ItemizeStruc(LATEX_INDENT, indentSize);
  4298.       itemizeStack.Insert(struc);
  4299.       
  4300.       sprintf(buf, "\\tx%d\\li%d\\lr%d\\box%s ", indentSize, indentSize, indentSizeRight,
  4301.         ((macroId == ltCENTEREDBOX) ? "\\brdrs" : "\\brdrdb"));
  4302.       PushEnvironmentStyle(buf);
  4303.       TexOutput(buf);
  4304.       return FALSE;
  4305.     }
  4306.     if (!start && (arg_no == 2))
  4307.     {
  4308.       PopEnvironmentStyle();
  4309.       if (itemizeStack.First())
  4310.       {
  4311.         ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
  4312.         delete struc;
  4313.         delete itemizeStack.First();
  4314.       }
  4315.       if (itemizeStack.Number() == 0)
  4316.       {
  4317.         TexOutput("\\par\\pard\n");
  4318.         issuedNewParagraph = TRUE;
  4319.         WriteEnvironmentStyles();
  4320.       }
  4321.     }
  4322.     return TRUE;
  4323.     break;
  4324.   }
  4325. */
  4326.   case ltDOCUMENTSTYLE:
  4327.   {
  4328.     DefaultOnArgument(macroId, arg_no, start);
  4329.     if (!start && !IsArgOptional())
  4330.     {
  4331.       if (MinorDocumentStyleString)
  4332.       {
  4333.         if (StringMatch("twoside", MinorDocumentStyleString))
  4334.           // Mirror margins, switch on odd/even headers & footers, and break sections at odd pages
  4335.           TexOutput("\\margmirror\\facingp\\sbkodd");
  4336.         if (StringMatch("twocolumn", MinorDocumentStyleString))
  4337.           TexOutput("\\cols2");
  4338.       }
  4339.       TexOutput("\n");
  4340.     }
  4341.     return FALSE;
  4342.   }
  4343.   case ltBIBITEM:
  4344.   {
  4345.     if (arg_no == 1 && start)
  4346.     {
  4347.       char *citeKey = GetArgData();
  4348.       TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
  4349.       if (ref)
  4350.       {
  4351.         if (ref->sectionNumber) delete[] ref->sectionNumber;
  4352.         sprintf(buf, "[%d]", citeCount);
  4353.         ref->sectionNumber = copystring(buf);
  4354.       }
  4355.  
  4356.       TexOutput("\\li260\\fi-260 "); // Indent from 2nd line
  4357.       sprintf(buf, "{\\b [%d]} ", citeCount);
  4358.       TexOutput(buf);
  4359.       citeCount ++;
  4360.       return FALSE;
  4361.     }
  4362.     if (arg_no == 2 && !start)
  4363.       TexOutput("\\par\\pard\\par\n\n");
  4364.     return TRUE;
  4365.     break;
  4366.   }
  4367.   case ltTHEBIBLIOGRAPHY:
  4368.   {
  4369.     if (start && (arg_no == 1))
  4370.     {
  4371.       citeCount = 1;
  4372.       if (winHelp)
  4373.         SetCurrentOutputs(Contents, Chapters);
  4374.  
  4375.       if (!winHelp)
  4376.       {
  4377.         fprintf(Chapters, "\\sect\\pgncont\\titlepg\n");
  4378.  
  4379.         // If a non-custom page style, we generate the header now.
  4380.         if (PageStyle && (strcmp(PageStyle, "plain") == 0 ||
  4381.                           strcmp(PageStyle, "empty") == 0 ||
  4382.                           strcmp(PageStyle, "headings") == 0))
  4383.         {
  4384.           OutputRTFHeaderCommands();
  4385.           OutputRTFFooterCommands();
  4386.         }
  4387.         
  4388.         // Need to reset the current numbering style, or RTF forgets it.
  4389.         OutputNumberStyle(currentNumberStyle);
  4390.         SetCurrentOutput(Contents);
  4391.       }
  4392.       else
  4393.         fprintf(Chapters, "\\page\n");
  4394.  
  4395.       if (winHelp)
  4396.         fprintf(Contents, "\n{\\uldb %s}", ReferencesNameString);
  4397.       else
  4398.         fprintf(Contents, "\\par\n\\pard{\\b %s}", ReferencesNameString);
  4399.  
  4400.       startedSections = TRUE;
  4401.  
  4402.       if (winHelp)
  4403.         fprintf(Chapters, "\n${\\footnote %s}", ReferencesNameString);
  4404.  
  4405.       char *topicName = "bibliography";
  4406.  
  4407.       if (winHelp)
  4408.         fprintf(Contents, "{\\v %s}\\par\\pard\n", topicName);
  4409.       else
  4410.         fprintf(Contents, "\\par\\par\\pard\n");
  4411.  
  4412.       if (winHelp)
  4413.       {
  4414.         fprintf(Chapters, "\n#{\\footnote %s}\n", topicName);
  4415.         fprintf(Chapters, "+{\\footnote %s}\n", GetBrowseString());
  4416.         fprintf(Chapters, "K{\\footnote %s}\n", ReferencesNameString);
  4417.         GenerateKeywordsForTopic(topicName);
  4418.         if (useUpButton)
  4419.         {
  4420.           fprintf(Chapters, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
  4421.                FileNameFromPath(FileRoot), "Contents");
  4422.         }
  4423.       }
  4424.       
  4425.       SetCurrentOutput(Chapters);
  4426.       char *styleCommand = "";
  4427.       if (!winHelp && useHeadingStyles)
  4428.         styleCommand = "\\s1";
  4429.       fprintf(Chapters, "\\pard{%s", (winHelp ? "\\keepn" : styleCommand));
  4430.       WriteHeadingStyle(Chapters, 1);  fprintf(Chapters, " References\\par\\pard}\n");
  4431.  
  4432.       return FALSE;
  4433.     }
  4434.     return TRUE;
  4435.     break;
  4436.   }
  4437.   case ltINDEX:
  4438.   {
  4439.     /*
  4440.      * In Windows help, all keywords should be at the start of the
  4441.      * topic, but Latex \index commands can be anywhere in the text.
  4442.      * So we're going to have to build up lists of keywords for a topic,
  4443.      * and insert them on the second pass.
  4444.      *
  4445.      * In linear RTF, we can embed the index entry now.
  4446.      *
  4447.      */
  4448.     if (start)
  4449.     {
  4450.       char *entry = GetArgData();
  4451.       if (winHelp)
  4452.       {
  4453.         if (CurrentTopic)
  4454.         {
  4455.           AddKeyWordForTopic(CurrentTopic, entry);
  4456.         }
  4457.       }
  4458.       else GenerateIndexEntry(entry);
  4459.     }
  4460.     return FALSE;
  4461.     break;
  4462.   }
  4463.   case ltFCOL:
  4464.   case ltBCOL:
  4465.   {
  4466.     if (start)
  4467.     {
  4468.       switch (arg_no)
  4469.       {
  4470.         case 1:
  4471.         {
  4472.           char *name = GetArgData();
  4473.           int pos = FindColourPosition(name);
  4474.           if (pos > -1)
  4475.           {
  4476.             sprintf(buf, "{%s%d ", ((macroId == ltFCOL) ? "\\cf" : "\\cb"), pos);
  4477.             TexOutput(buf);
  4478.           }
  4479.           break;
  4480.         }
  4481.         case 2:
  4482.         {
  4483.           return TRUE;
  4484.           break;
  4485.         }
  4486.         default:
  4487.           break;
  4488.       }
  4489.     }
  4490.     else
  4491.     {
  4492.       if (arg_no == 2) TexOutput("}");
  4493.     }
  4494.     return FALSE;
  4495.     break;
  4496.   }
  4497.   case ltLABEL:
  4498.   {
  4499. /*
  4500.     if (start && !winHelp)
  4501.     {
  4502.       char *s = GetArgData();
  4503.       fprintf(Chapters, "{\\*\\bkmkstart %s}{\\v BOOKMARK}{\\*\\bkmkend %s}", s,s);
  4504.     }
  4505. */
  4506.     return FALSE;
  4507.     break;
  4508.   }
  4509.   case ltPAGEREF:
  4510.   {
  4511.     if (start && !winHelp)
  4512.     {
  4513.       char *s = GetArgData();
  4514.       fprintf(Chapters, "{\\field{\\*\\fldinst  PAGEREF %s \\\\* MERGEFORMAT }{\\fldrslt ??}}",
  4515.               s);
  4516.     }
  4517.     return FALSE;
  4518.     break;
  4519.   }
  4520.   default:
  4521.   {
  4522.     return DefaultOnArgument(macroId, arg_no, start);
  4523.     break;
  4524.   }
  4525.   }
  4526.   return TRUE;
  4527. }
  4528.  
  4529. Bool RTFGo(void)
  4530. {
  4531.   // Reset variables
  4532.   indentLevel = 0;
  4533.   forbidParindent = 0;
  4534.   contentsLineSection = NULL;
  4535.   contentsLineValue = NULL;
  4536.   descriptionItemArg = NULL;
  4537.   inTabular = FALSE;
  4538.   inTable = FALSE;
  4539.   inFigure = FALSE;
  4540.   startRows = FALSE;
  4541.   tableVerticalLineLeft = FALSE;
  4542.   tableVerticalLineRight = FALSE;
  4543.   noColumns = 0;
  4544.   startedSections = FALSE;
  4545.   inVerbatim = FALSE;
  4546.   browseId = 0;
  4547.   
  4548.   if (InputFile && OutputFile)
  4549.   {
  4550.     // Do some RTF-specific transformations on all the strings,
  4551.     // recursively
  4552.     Text2RTF(GetTopLevelChunk());
  4553.  
  4554.     Contents = fopen(TmpContentsName, "w");
  4555.     Chapters = fopen("chapters.rtf", "w");
  4556.     if (winHelp)
  4557.     {
  4558.       Sections = fopen("sections.rtf", "w");
  4559.       Subsections = fopen("subsections.rtf", "w");
  4560.       Subsubsections = fopen("subsubsections.rtf", "w");
  4561.       Popups = fopen("popups.rtf", "w");
  4562.       if (!Sections || !Subsections || !Subsubsections || !Popups)
  4563.       {
  4564.         OnError("Ouch! Could not open temporary file(s) for writing.");
  4565.         return FALSE;
  4566.       }
  4567.     }
  4568.     if (!Contents || !Chapters)
  4569.     {
  4570.       OnError("Ouch! Could not open temporary file(s) for writing.");
  4571.       return FALSE;
  4572.     }
  4573.  
  4574.     if (winHelp)
  4575.     {
  4576.       fprintf(Chapters, "\n#{\\footnote Contents}\n");
  4577.       fprintf(Chapters, "${\\footnote Contents}\n");
  4578.       fprintf(Chapters, "+{\\footnote %s}\n", GetBrowseString());
  4579.       fprintf(Chapters, "K{\\footnote %s}\n", ContentsNameString);
  4580.       fprintf(Chapters, "!{\\footnote DisableButton(\"Up\")}\n");
  4581.     }
  4582.     if (!winHelp)
  4583.     {
  4584.       fprintf(Chapters, "\\titlepg\n");
  4585.       fprintf(Contents, "\\par\\pard\\pgnrestart\\sect\\titlepg");
  4586.     }
  4587.     
  4588.     // In WinHelp, Contents title takes font of title.
  4589.     // In linear RTF, same as chapter headings.
  4590.     fprintf(Contents, "{\\b\\fs%d %s}\\par\\par\\pard\n\n",
  4591.       (winHelp ? titleFont : chapterFont)*2, ContentsNameString);
  4592.  
  4593.     // By default, Swiss, 10 point.
  4594.     fprintf(Chapters, "\\f2\\fs20\n");
  4595.  
  4596.     SetCurrentOutput(Chapters);
  4597.  
  4598.     OnInform("Converting...");
  4599.     TraverseDocument();
  4600.  
  4601.     FILE *Header = fopen("header.rtf", "w");
  4602.     if (!Header)
  4603.     {
  4604.       OnError("Ouch! Could not open temporary file header.rtf for writing.");
  4605.       return FALSE;
  4606.     }
  4607.     WriteRTFHeader(Header);
  4608.     fclose(Header);
  4609.     
  4610.     Tex2RTFYield(TRUE);
  4611.     if (winHelp)
  4612.     {
  4613. //      fprintf(Contents, "\\page\n");
  4614.       fprintf(Chapters, "\\page\n");
  4615.       fprintf(Sections, "\\page\n");
  4616.       fprintf(Subsections, "\\page\n");
  4617.       fprintf(Subsubsections, "\\page\n\n");
  4618.       fprintf(Popups, "\\page\n}\n");
  4619.     }
  4620.  
  4621. //    TexOutput("\n\\info{\\doccomm Document created by Julian Smart's Tex2RTF.}\n");
  4622.     if (!winHelp)
  4623.       TexOutput("}\n");
  4624.     fclose(Contents);
  4625.     fclose(Chapters);
  4626.     if (winHelp)
  4627.     {
  4628.       fclose(Sections);
  4629.       fclose(Subsections);
  4630.       fclose(Subsubsections);
  4631.       fclose(Popups);
  4632.     }
  4633.  
  4634.     if (winHelp)
  4635.     {
  4636.       wxConcatFiles("header.rtf", "chapters.rtf", "tmp1.rtf");
  4637.       Tex2RTFYield(TRUE);
  4638.       wxConcatFiles("tmp1.rtf", "sections.rtf", "tmp2.rtf");
  4639.       Tex2RTFYield(TRUE);
  4640.       wxConcatFiles("tmp2.rtf", "subsections.rtf", "tmp3.rtf");
  4641.       Tex2RTFYield(TRUE);
  4642.       wxConcatFiles("tmp3.rtf", "subsubsections.rtf", "tmp4.rtf");
  4643.       Tex2RTFYield(TRUE);
  4644.       wxConcatFiles("tmp4.rtf", "popups.rtf", OutputFile);
  4645.       Tex2RTFYield(TRUE);
  4646.  
  4647.       wxRemoveFile("tmp1.rtf");
  4648.       wxRemoveFile("tmp2.rtf");
  4649.       wxRemoveFile("tmp3.rtf");
  4650.       wxRemoveFile("tmp4.rtf");
  4651.     }
  4652.     else
  4653.     {
  4654.       wxConcatFiles("header.rtf", "chapters.rtf", "tmp1.rtf");
  4655.       Tex2RTFYield(TRUE);
  4656.       if (FileExists(OutputFile)) wxRemoveFile(OutputFile);
  4657.       wxCopyFile("tmp1.rtf", OutputFile);
  4658.       Tex2RTFYield(TRUE);
  4659.       wxRemoveFile("tmp1.rtf");
  4660.     }
  4661.     
  4662.     if (FileExists(ContentsName)) wxRemoveFile(ContentsName);
  4663.     wxRenameFile(TmpContentsName, ContentsName);
  4664.  
  4665.     wxRemoveFile("chapters.rtf");
  4666.     wxRemoveFile("header.rtf");
  4667.       
  4668.     if (winHelp)
  4669.     {
  4670.       wxRemoveFile("sections.rtf");
  4671.       wxRemoveFile("subsections.rtf");
  4672.       wxRemoveFile("subsubsections.rtf");
  4673.       wxRemoveFile("popups.rtf");
  4674.     }
  4675.     if (winHelp && generateHPJ)
  4676.       WriteHPJ(OutputFile);
  4677.     return TRUE;
  4678.   }
  4679.   return FALSE;
  4680. }
  4681.  
  4682.